"CUPS did not, of course, work. It's not supposed to, it's CUPS"
(A friend of mine who is not a CUPS fan. The same friend also sent me an acroynym he'd found on the web: CUPS=Can't Usually Print Stuff)
"CUPS is specifically designed to retrain those foolhardy enough to think that they should try to print."
(Another person who isn't a big fan of CUPS)

My favorite however, comes from Dr. Stephen Turnbull who felt that in the spirit of GNU, it should be a recursive acronym.

CUPS: Unusable Printer Solution

Cups Problems

A quick note. This page has become quite dated. CentOS users might find this CentOS forums post quite useful.

I'm never sure if it should be written CUPS, Cups or something else, so I'm just going to be using cups as it's easiest to type. Hopefully, that won't bother anyone.

When cups works correctly, out of the box, it makes setting up a printer almost as easy as an MS point and click setup. While many purists would probably disagree, to me this is a Good Thing(TM). Setting up printers is not one of my favorite chores.

While many people do prefer the web interface, I prefer the command line--it's faster than point and clicking through steps of the web. As most of the time, especially at work, I'm adding networked printers, attached to JetDirects, as root or with root privilege--in this case, we'll call the printer ACCTHP, with a JetDirect at 192.168.1.15

lpadmin -p ACCTHP -E -v socket://192.168.1.15 -m laserjet.ppd
For a printer attached by a parallel port, the command would be
lpadmin -p ACCTHP -E -v parallel://dev/lpt0 -m laserjet.ppd

The -p is the printer name, the -E enables it, -v is for the device and -m is for the ppd file. The various forms of syntax are found in the cups documentation, this happens to be the one I am used to. A list of the available ppds can be found in /usr/local/share/cups/model on FreeBSD. The location on your system will depend upon where 3rd party software share items are installed. CUPS looks for the ppd in that model directory. (See the section on hpijs below). If it works the way it's supposed to, it's quite easy.

The documentation is changing. With version 1.2, in FreeBSD at least, the CUPS System Administrator Manual is no longer included. (The manual is for system 1.1 but much of it has remained the same.) The manual can still be found online at the cups website. The documentation for version 1.2.x concentrates upon the web interface. However, the command line options are still available.

Most of it can be done with the lpadmin command, using the syntax lpadmin -p (printername) command or options. For example, to use the enable command for our ACCTHP laserjet printer
lpadmin -p ACCTHP -E

In the most recent versions of cups, the enable and disable commands are actually called cupsenable and cupsdisable. To enable ACCTHP I could use, instead of the example above
cupsenable ACCTHP
I would disable it with cupsdisable. (I haven't found a way to disable with lpadmin, however, I've never looked.)

It is often worthwhile, if you have an HP printer, to install the hpijs program. The basic cups has generic laserjet and deskjet drivers. The hpijs program has more specific drivers for a large range of HP printer models.

If your distribution or operating system doesn't have a package, you can grab the the HPLIP source from the HPLIP home page. As all the systems I use have it as a package or port, I've never installed it from source, but instructions are there on the website. It includes the hpijs package.

Note that to install one of the drivers (which are usually put in your share/cups/model directory, if you use lpadmin, you have to put the path, starting from the model directory. For example, in FreeBSD, the model directory is in /usr/local/share/cups. Upon installation, the hpijs program creates a foomatic-ppds directory in the model directory and an HP directory in that foomatic-ppds directory.

So, if I were using lpadmin in FreeBSD, to modify the ppd file for our ACCTHP printer, if it were a LaserJet 4000
lpadmin -p ACCTHP -m foomatic-ppds/HP/HP_LaserJet_4000_Series.ppd.gz

(That isn't a typo. The ppds are stored as gzipped files and the above syntax works.)

Often, the ppds aren't made unless you ask for them. Instead, the database is stored as an xml file. Cups' web interface will be able to generate a ppd file from it. You can also use the foomatic-ppdfile supposedly. Its man page is pretty horrible. For those who want to try it, instructions follow. (In honestly, it's probably quicker to use the cups web interface, but many people, including myself, are often working in remote sessions without X.) One page I've found on it is here. The way I did it was find the ppd file in (with ArchLinux), /usr/share/foomatic/db/source/printer. My printer, a Brother 2170-W was listed as Brother-HL-2170W.xml. I then ran the command (this should be on one line)
foomatic-ppdfile -p 'Brother-HL-2170W' > /usr/share/cups/model/Brother-HL2170W.ppd

This generated the ppd file, and from there, I was able to use the lpadmin command as explained above.

I'm not sure if the above is still true. It seems, at least in RH based systems, that now the system will rely on a c++ file in /usr/share/cups/drv, at least for HP printers. In that directory, I have a subdirectory, hp, with two c++ programs in it, hpcups.drv and hpijs.drv. It seems, at least when I use hplip, that this will find the printer, figure out its type, and then create a ppd. If I remove the printer, the ppd is also removed. I haven't figured out how to work this manually yet.

To see a list of printers, one can use
lpstat -p

Running lpstat -p -d will show the default printer if there is one. To set default printer, use lpoptions -d <printer_name>, e.g.
lpoptions -d ACCTHP

Despite cups' having greatly improved over the years, many people have problems with cups--I've found, going to google that if you put in that client-error message, you get many many hits--but few solutions. So, through googling, trial and error, and various mailing lists and forums, I've come up with some common gotchas and relatively easy fixes.

(Note that some of these are old problems--though I maintain this page from time to time, I leave the old problems and their solutions here, because they might pop up again.)

The cups documentation is good in a way--however, one hopes that eventually, they will be able to cover some of these small details in the setup procedures. So, without further ado...

I've used Gentoo Linux as my cups server, serving other Linux (and FreeBSD) clients, as well as MS clients using Samba, and these days use FreeBSD as the Server. To my amusement, with both of them I've had times where the MS clients could print from the server, but I couldn't print locally. Here are the small problems I've run into with cups.

Gentoo Linux

From time to time, Gentoo has various problems with circular dependencies. One tries to emerge cups, which needs ghostscript which needs gimp-print. However, gimp-print needs cups. So, the whole emerge process fails. The work around for that one (which will probably, judging from Gentoo's track record, gets fixed relatively quickly, is to emerge with the --nodeps option. As it's still being worked on, I can't say it will always work by doing ghostscript --nodeps then gimp-print --nodeps then cups, but I believe that is the order I used the last time.

It is also necessary to specify cups as a USE variable in /etc/make.conf. Lastly, after emerging cups, emerge ghostscript again. This seems to solve most of the problems judging from postings on the mailing lists and forums.

If cups is going to be used as a print server in conjunction with samba, there are a few adjustments to be made to smb.conf, mainly specifying that client machines will use their own drivers. This is covered on my samba page in the printing section. (As I haven't used Gentoo in a long time, I'm not sure if this is still an issue or not).

FreeBSD and NetBSD

With FreeBSD, cups will place its configuration files in /usr/local/etc rather than /etc. The lp or lpr command that you will use is also going to be in /usr/local/bin rather than /usr/bin. As /usr/bin is listed first in the path for both root and normal user, if one tries to print using the command lp filename you'll get an error message.

There are various workarounds--one can edit the $PATH variable, type the entire path, eg /usr/local/bin/lp or do it the lazy man's way, which, as those who know me would expect, is what I did. I backed up the /usr/bin lp and lpr and then sym linked /usr/local/bin's commands to them.

mv /usr/bin/lp /usr/bin/lp.bak
mv /usr/bin/lpr /usr/bin/lpr.bak
ln -s /usr/local/bin/lp /usr/bin/lp
ln -s /usr/local/bin/lpr /usr/bin/lpr

This solved that problem, but I had to do it each time I did a makeworld. The answer was given me by a gentleman known as Jelle, who saw this page and was kind enough to email me the solution. Simply edit /etc/make.conf. In there is a line which reads

#NO_LPR= true

Remove the # at the beginning of the statement to uncomment it and you won't have to relink /usr/local/bin/lp and /usr/local/bin/lpr each time. Sometimes, the line is not in /etc/make.conf. If that's the case, simply add it, without, of course, the # at the beginning.

Note that in later versions of FreeBSD, the line has been changed to
NO_LPR=

(check your /usr/share/examples/etc/make.conf for proper syntax)

Someone who saw this page told me that if, while leaving in those lines, one also adds

CUPS_OVERWRITE_BASE=yes

in /etc/make.conf one should not have to symlink /usr/local/bin/lp and lpr to /usr/bin. There is now a message to this effect in the cups-lpr port. To check if it's necessary, after installation do
ls -l /usr/bin/lp

If you see something like
lrwxr-xr-x  1 root  wheel  17 Jan 10 14:22 /usr/bin/lp -> /usr/local/bin/lp

then it isn't necessary to do the mv lp and lpr to lp.bak and lpr.bak. (For newcomers,the important thing here is the -> /usr/local/bin/lp. That shows /usr/bin/lp has been linked to cups' /usr/local/bin/lp.)

Another issue I had on a recent install...I installed Samba first, which installed CUPS. However, there was no /usr/local/bin/lp and lpr. I went back into /usr/ports/print/cups and went to install cups-base. It was already installed. I then installed /usr/ports/print/cups-lpr which fixed that problem. However, it still wasn't working properly. At this point, I just installed /usr/ports/print/cups and then everything worked. I'm not sure why I have never run into this before, and only mention it in case the reader runs into something similar. Perhaps I've always, up to now, installed cups before Samba, I honestly don't remember.

A gentleman named Rik, who read this page, gave me another problem and solution that he had. When trying to print something as root from a client machine, nothing would print. (Both machines running FreeBSD). He solved the problem by, as root, doing

setenv TMPDIR /tmp

This fixed his problem.

One last odd one--at one point, running FreeBSD-5.2 I installed, in addition to ghostscript-gnu, ghostscript-gnu-commfont which adds some extra Asian fonts. Once I did that, however, everything stopped working. As soon as I uninstalled it, everything began working again.

On NetBSD, I've found that cups will only work if one installs ghostscript-eps as opposed to ghostscript-gnu or the other choices.

RedHat Linux

RedHat's lp command does not, in the default installation, refer to cups. However, they have a tool something like redhat-switch-printer that will fix that. It has to be run in X. I only did it once, and don't remember the exact command, but if you type, as root,
redhat-switch-printer

it should work. If not, try redhat-switch-print.

Also--I have only heard of this happening with RH and Fedora, but may occur with other distros. If you choose to install everything, both LPrng and CUPS get installed, but the lp and lpr commands refer to LPrng. So, if you don't remove it, or do the switch-printer thing, you might wind up with error messages along the lines of

error msg: 'spool queue for HP1100 does not exist on server nyserve3.localhost
error msg: ' non-existent printer or you need to run 'checkpc -f'

If you then run checkpc -f you'll get a message about problems with /etc/printcap. What's happening is that is that lp and lpr commands are for LPrng but you're trying to print with CUPS. (This also happened to me on a FreeBSD test box. I'd installed LPrng and forgotten that I'd done so.)

Another thing that can affect cups, especially with samba--be sure you have an entry for your local host in /etc/hosts. This may be distro specific, as it happened to someone using Arch Linux, a relatively obscure, though very nice and fast distro that will probably take off sooner or later. However, I'm not sure, as I always have my host name in /etc/hosts.

Cups on a client machine

If the Linux or FreeBSD box is the client, be sure to go into your /cups/client.conf file and enter the server name, which is commented out and will use something like "myhost.domain.com" by default. For instance, my client machines print to my Gentoo cups server at 192.168.1.100, so each of them has the following entry in cups/client.conf
ServerName 192.168.1.100

I haven't, however, found this necessary when using a JetDirect. If the *nix machine is simply printing to a networked printer, hooked up to a JetDirect card, you can use the JetDirect's IP Address, use the socket option when it's offered and in the next screen put in something like

Socket://192.168.1.5

Another thing that sometimes is an issue is, when you're using lpd on the client, the server's xinetd.d/cups-lpd file. Make sure that it's set to

disable = no

Another thing is the default /cups/conf.d file--by default it denies all and reads Deny before Allow. (This is in the Location section) Since, at present, I'm just using it on a home network, I just reversed the order and put in the two addresses I needed to allow

Order Allow, Deny
Allow From 192.168.1.103
Allow From 192.168.1.104

Recently, after a vulnerability was discovered an upgrade to cups was quickly released. Since then, although priniting to my DeskJet was still simple, printing to LaserJets required having ghostscript installed. I would send a job to the printer, my screen would show it was going, but nothing was happening--the logs specifically suggested that I add ghostscript, which I did. This fixed that particular problem.

Sometimes, running cups in conjunction with Samba, an MS box will indicate that it's printing, but nothing happens--the cups error log will usually show something like unsupported format 'application/octet-stream' or something similar. In that case in your /etc/cups directory, there is a file called mime.convs. At the end is a line referring to octet-stream. In general, it's commented out, when I've had this problem, uncommenting it and restarting the cups daemon fixed the problem.

The next issue is probably obvious, but worth mentioning, as I missed it. Later versions of Mac OSX also use cups. I tried to set my wife's iBook to print to the HP DeskJet on the FreeBSD box without success. Not only that, but something got borked in the permissions, so that the cheap local USB Epson would no longer work.

It turned out that I'd never added her to the users on the FreeBSD box. As soon as I did that, the iBook was able to print to the DeskJet on the FreeBSD box without problem.

One thing I have found when using samba is that one some boxes, although everything will work, you will get a message about access being denied on the MS box. Someone told me (I don't remember who, so cannot give them credit) that this is usually fixed by adding

use client driver = yes

to the [printers] section fixed that error.

One last one, for folks with an 840c Deskjet. I don't remember how I found this out, but at any rate, on Windows 2000 and Windows XP, using HP's install disk doesn't work. Use the drivers for the 660c and that will often work. If it doesn't, then use the drivers for the 550c. I never researched this deeply. I Found the solution on deja at some point. When I did a reinstall of Win2k on a particular box, I'd forgotten about it and spent a couple of days examining cups and samba logs, trying to figure out what was wrong. In the end, I happened to remember it, reinstalled the printer with the 660c drivers and everything was fine. For comic relief I might as mention the time when I couldn't figure out what I had done wrong on the client--I'd set it up as I usually do, but nothing was printing, I was getting a message that the server was unavailable. It turned out that I'd stopped the cups daemon on the server and never restarted it. So, it never hurts to check the obvious.

Another one that might be considered comic relief. A user's printer suddenly stopped working. Restarted cups and smbd and nmbd. Checked the obvious, connections and the like. This is an HP3500 color printer and it showed that the cyan was low. I ignored that as with the higher end printers we have, 4500's and 4550's, that has never been an issue. Also, printing directly from the printer with the test button worked.

At any rate, after trying everything else, I replaced the cyan toner. It fixed the problem. In this case, it wasn't a cups issue, I simply mention it as an example of how we can overlook the obvious.

Well, these are the little issues that I've had with cups. If you have some of your own, then please drop me a line. I'm not looking for complicated configuration files--I'm simply looking for little quick fixes that aren't covered in the basic setup documentation. You can send me your funny stories if you want, that is, things like my forgetting to start the daemon, but they won't get put up here. I'm looking for the little simple tips, such as adding the ServerName to the client.conf file

Jim B. sent me the following--it's one that I haven't run into, as I don't use KDE

"I have KDE 3.2.2 on FreeBSD 4.10-RC2, KDEPrint using CUPS (latest
version),
and the latest foomatic packages.

"I could not get the Printing Manager to display more than a few simple
printer models- just Danka, EPS, and GENERIC.
  
"Turns out, the Printing Manager runs a script called
'make_driver_db_cups' when you create the first printer. This
script has no documentation, but I managed to figure out that it
looks for the driver configurations in /usr/share/cups/model AND
/usr/share/foomatic/db/source.  Not the usual BSD paths so I
performed:

ln -s /usr/local/share/cups /usr/share/cups
ln -s /usr/local/share/foomatic /usr/share/foomatic

"and restarted cupsd.  When I next tried to add a printer,
the Printing Manager went out and found all the other drivers.
   
I now have $many++ printer drivers available."

Another helpful tip from Paul B. having to do with default margins and banners.

How to set printer default attributes for clients. The doc says we are supposed to be able to use lpoptions without the -p printer to set default attributes to apply for all printers. I haven't found that to work. In addition I found that if I set lptoption attributes for all my printers on the server, my clients don't inherit the attributes. I noticed that the browser set attributes by both modifiying the printers.conf file in / etc/cups and the ppd files in /etc/cups/ppd. I did the same thing and it works great. I use the printers.conf file to set the banner default, and the ppd file to set the margins default for printing text files.

A couple of good links:
One very nice howto, (though ArchLinux specific, much of it can be applied to most systems) can be found here.

Another excellent howto more oriented towards FreeBSD (but again, helpful for any O/S) is on the excellent bsdnexus.com site. The CUPS howto is here.

Cups 1.2 as of June, 2006

Cups 1.2 is out, and has several problems. Hopefully, they'll be fixed sooner or later.

One problem that has shown up in both FreeBSD and various Linux distros is that one often has problems printing if the printer is directly attached by parallel or USB. One workaround for FreeBSD was given in a problem report. If one views the PR, they can see the workaround for USB. You will also see a comment that I made that it worked for me with parallel printing as well. However, rather than add lines to devfs.rules I add the following to /etc/devfs.conf.
own     lpt0 root:cups
perm    lpt0 0660

This enabled local printing. However, on this one machine, running CURRENT, printing from Windows printers didn't work. As mentioned earlier in this article, there is a line in mime.convs and mime.types for application/octet-stream that usually needs to be uncommented if you printing from Windows machines. When I upgraded to cups-1.2 on a box running CURRENT, uncommenting those lines didn't work. I would get the error message (also mentioned above) that application/octet-stream was unsupported. I didn't have the problem on a box running 6.1-STABLE.

It seems to be a known bug that is fixed, despite not not working for me on this one machine. See this thread on the cups website.

However, there is a workaround given in the thread mentioned above which I used. Adding
cups options = raw

to /etc/smb.conf is one solution, however, it didn't work for me.

In FreeBSD, if one does choose to be daring and install 1.2, you will first have to pkg_delete cups-lpr. I recommend being sure that you still have the port directory in case you have to reinstall it. I would also recommend making a package for cups-base. This is done with the pkg_create command.
pkg_create -b cups-base-1.1.23.0_9

(One can also use portupgrade with the -b option, to make backups of packages before installing the new one.) You can store that package anywhere, then, if you have problems with 1.2 replace it with pkg_add. I found that I had to reinstall cups-lpr, however, by using the port's Makefile, otherwise, I got a message about a missing pkgconfig.

The documention for cups-1.2 is still lacking. In FreeBSD, if one uses the web interface, at time of writing both the option for a USB connection and parallel connection are missing. I still had my old printers.conf, but one can also use lpadmin. The older version's docs included the Cups administrator's manual, which gave a thorough explanation of using the command line to manage printers. Hopefully, as 1.2 matures, the docs will catch up with it.

The FreeBSD port is up to version 1.2.2. There is now a pkg-message when one installs cups-base, giving the steps for using a directly connected printer.

The 1.2.x version of cups has a somewhat different default cupsd.conf. The Location section will read
# Restrict access to the server...
<Location />
  Order allow,deny
  Allow localhost
</Location>

This will only allow printing from the localhost. Note that the order is allow, deny, so that even if you then put a line to Deny none, it would still only allow the localhost. Although the new default file is far less commented than the old, the old syntax, Allow from 192.168.1.* and the like, still work.