If you set up CUPS on an OS X Server (version 10.8.5 in my case, but anything from 10.7 (where CUPS introduced sandboxing) through 10.9 (the current version) should exhibit this behavior), i.e. you enable Printer Sharing in System Preferences and run sudo cupsctl WebInterface=yes, and leave the system running for a few days, you’ll eventually run into the situation that http://localhost:631/printers will report “Internal Server Error”, and clients will no longer be able to print to the server.
Digging around CUPS’ debug log, you’ll see something like
D [27/Oct/2013:13:33:52 +0100] [CGI] sandbox_init failed: /private/tmp/05d735269fa67: No such file or directory (No such file or directory)
D [27/Oct/2013:13:33:52 +0100] PID 78980 (/usr/libexec/cups/cgi-bin/printers.cgi) stopped with status 1.
That missing file (named a different 13-digit hexadecimal name upon each restart) is the CUPS daemon’s sandbox profile.
Digging around further reveals that /var/log/daily.out contains exactly this file name:
Sun Oct 27 03:15:01 CET 2013
Removing old temporary files:
/tmp/05d735269fa67
[...]
All we need to do to prevent this from happening in the future is opening /etc/periodic/daily/110.clean-tmps in your favorite text editor and adding the line printed in bold:
set -f noglob
args="-atime +$daily_clean_tmps_days -mtime +$daily_clean_tmps_days"
args="${args} -ctime +$daily_clean_tmps_days"
args="${args} ! -group _lp ! -user _lp"
dargs="-empty -mtime +$daily_clean_tmps_days"
dargs="${dargs} ! -name .vfs_rsrc_streams_*"
Update February 2014: CUPS 1.7.1 is supposed to fix that issue; the release notes mention my reported bug. Now lets see how long it takes until Apple ships the updated CUPS with an OS X update.
Update March 2014: I just upgraded our server to OS X 10.9.2 and got CUPS 1.7.1 with it. Hooray, less than three months between bug reported and fix deployed. The sandbox profile now gets written to /var/spool/cups/tmp. In fact, that’s exactly what was changed in scheduler/conf.c in the CUPS source code: they added setenv("TMPDIR", TempDir, 1);