Techniques to deal with printing problems on the CUPS based printing system.
- The PDF-centric Workflow
- The CUPS Error Log
- Capturing the File Received by CUPS
- Capturing the File Sent to the Printer
- Backends and the Device URI of a Print Queue
- Testing a Backend and a Printer
- Problems Printing to a PostScript Printer
- Problems Printing to a USB Connected Printer
- Problems Printing to a Network Connected Printer
- Problems Printing with the IPP Backend
- Problems with mdns/DNS-SD
- Reporting Bugs
- See Also
The aim in this page and the sections of the wiki linked from it is to give some insight on printing with CUPS in Debian 8 (Jessie) and Debian 9 (Stretch). There are differences between the two distributions but the filtering systems are identical in principle and nearly so in practice. It is hoped that there will be sufficient detail to give an understanding of how parts of CUPS and the filtering system work and co-operate and to enable effective troubleshooting.
CUPS (a product of Apple Inc.) is the manager of all printing processes via its scheduler, cupsd. It also provides a number of filters which prepare a print job for sending to a printer. However, some filters essential for Linux systems were not required by Apple and were donated to the Linux Foundation and now form the basis for the cups-filters and cups-filters-core-drivers packages in Debian. When we take the contributions of developers of other free software such as Ghostscript, Poppler, Gutenprint and Avahi into account we can glimpse the complexity of the relationships between the components of the printing system. In spite of this complexity the debugging methods described later can be very effective if used in a organised way.
Throughout this account CUPS is used to refer to what you get if the source is downloaded from cups.org and compiled. cups-filters is a Linux Foundation project which interworks with CUPS but responsibility for its maintenance lies with the Linux Foundation and openprinting, not CUPS.
The PDF-centric Workflow
Prior to Wheezy the filtering system was devised to process PostScript files; that is, any file recognised by CUPS as a known MIME media type was first converted to PostScript before being processed. At present we have a system which is designed to process files in PDF format; known MIME media types are first converted to a PDF if necessary.
An ideal chain of filtering would be
PDF in -> pdftopdf -> PDF out -> Printer which interprets PDF
PDF in is relatively easy to accomplish; we simply get applications to generate and send PDF, which is what Firefox/Iceweasel and Evince (amongst other applications) do by default. But not all applications do generate PDF and users still want to print text and PostScript files. Also, the printer may not understand PDF but require PostScript, PCL or some proprietary language. A generalised filtering chain would be
File in -> convert to PDF -> pdftopdf -> PDF out -> Convert to something the printer understands -> Printer
Note the initial conversion to PDF and the presence of the pdftopdf filter. This is a PDF-centric workflow.
There is one important situation (prior to CUPS 2.1.0 and cups-filters 1.10.0) in which cups-filters departs from the PDF workflow. That is when the input file is PostScript and the file is being sent to a PostScript printer. We should have
Postscript in -> pstopdf -> pdftopdf -> pdftops -> PostScript printer
but. although this generally works, it can introduce buggy behaviour such as delays and font problems because of the pstopdf and pdftops conversions. After a discussion the filter chain for PostScript job sent to a queue which feeds a printer which can interpret PostScript was altered and now uses pstops:
Postscript in -> pstops -> PostScript printer
pstops is a CUPS filter and is part of the older PostScript-centric workflow. A second situation where the PDF printing workflow is departed from occurs for PostScript from the Adobe Reader. Details are in /usr/share/cups/mime/cupsfilters.convs.
Since CUPS 2.1.0 the PPD files of the local print queues in /etc/cups/ppd/ are not world-readable as the default permissions of the ConfigFilePerm option in /etc/cups/cups-files are applied. A consequence is that the pstopdf shell script cannot read the PPD file of a print queue directly from the /etc/cups/ppd/ directory, so cups-filters 1.10.0 integrated the functionality of pstopdf into the gstoraster filter with the wrapper filter gstopdf. Post-1.10.0 the filter chain has become
PostScript in -> gstopdf -> pdftopdf -> PDF out -> Convert to something the printer understands -> Printer
The CUPS Error Log
For debugging the primary tool is the error log, /var/log/cups/error_log. Diagnosing printing problems is not always easy but without the error log it can make progress to a solution difficult. Don't forget that not everything which is in the error_log is the responsibilty of CUPS. Errors in the filtering chain are also logged there and could be the responsibilty of other programs such as cups-filters, Ghostscript, Poppler, colord etc, all non-CUPS software. In essence, CUPS has the task of spooling and scheduling print jobs and uses the error_log to make a record of this.
Also bear in mind the error_log may shed little light on some problems and other techniques and approaches may need to be employed. There could be misconfigurations in CUPS' files, the printer or a PPD file; the input file from an application might be defective in some way; the filter chain might be suboptimal for the job.
To enable debug logging (which is sufficient for most purposes):
For all the gory detail:
To turn off debug logging and return to LogLevel=warn:
cupsd will be restarted automatically after using any of these commands.
The file /etc/cups/cupsd.conf can also be edited by replacing LogLevel warn with LogLevel debug or (for masochists) LogLevel debug2. cupsd will need a manual restart if this is done:
systemctl restart cups
For reasons we will not go into here the error_log could have many lines saying cupsd is not idle any more, canceling shutdown. If you find them distracting the following command will remove them:
grep -v "not idle any more" /var/log/cups/error_log | less
It is not possible to give a complete account of what to look for in an error_log because the job and the setup in the CUPS configuration files cupsd.conf and cups-files will affect its contents. The presence of error and failed should ring alarm bells but tracking down the cause may not be as easy as one would like. Handy search terms are Auto-typing and filter. Both outcomes should conform with your expectations of how a job should be processed. A glance at argv is always worth it to see what options are being sent to CUPS.
The error_log may be emptied by root with
Capturing the File Received by CUPS
A file submitted for printing by an application or by lp/lpr first enters /var/spool/cups. If a print queue is disabled with
it stays there and does not enter the filtering subsystem. Such a file can be identified from its date-stamp and because its name will begin with a d. The file type can identified with the file utility and should be capable of being viewed to see what the application has sent. It can also be processed with cupsfilter to emulate the expected filtering process and examine what happens at each stage.
Re-enabling the print queue gets the file printed:
If you prefer to clear out /var/spool/cups there is
cancel -a -x
Capturing the File Sent to the Printer
Any print job can be printed to a file. As root, have FileDevice Yes in /etc/cups/cups-files.conf. Set up a print queue which prints to a file rather than sending to a printer. Either
lpadmin -p <print_queue> -v file:/tmp -E -m (or -P) <PPD_file>
or use the web interface.
What can be done with this printer-ready file? One possibility is that it might be capable of being viewed. If it looks fine the reason for a bad result on paper could lie with the backend used to send it to the printer or the way the printer interprets the file.
If the file cannot be viewed you could examine the previous stages which lead to its production and see whether they give acceptable outputs. If they do, you might begin to think in terms of three causes for the problem:
- The final filter.
- The backend used.
- A deficiency in the printer.
Backends and the Device URI of a Print Queue
Once the filtering system has produced a printer-ready file it is sent to the printer by a backend driver, which is really just another filter. The backend driver chosen is determined by the device-uri used when the print queue was deployed. For example,
lpadmin -p <print_queue> -v socket://<IP or hostname> -E -m <PPD_file>
would use the socket backend.
lists backend devices and is very useful for discovering if a printer or printer device is detected by CUPS.
Testing a Backend and a Printer
lp -d <print_queue> -o raw <printer-ready_file>
will avoid the filtering system entirely and use only a backend filter before the file is passed to the printer. A record of the transaction will be in the error_log. If there is a problem with the job being printed you can deduce it lies with either the backend (usb, socket, ipp etc) or the printer. To rule out the backend as a cause of a problem the printer-ready file can be sent directly to the printer.
For a printer connected to a parallel port:
cat <printer-ready_file> > /dev/lp0
For a USB connected printer
cat <printer-ready_file> > /dev/usb/lp0
It would be as well to check these are the correct usable devices on your system.
Network connected printers require a network-aware application such as netcat to process a file:
nc <printer_IP_or_host_name> <port> < <printer-ready_file>
Problems Printing to a PostScript Printer
It can sometimes happen that a file sent to a PostScript printer fails in some way. For example, an error message might be produced on the first page and subsequent pages are blank. The cause is thought to lie with buggy behaviour in the printer's PostScript interpreter even when given valid PostScript.
The filtering chain might be
PDF file -> pdftopdf -> pdftops -> PostScript -> printer
The pdftops filter has the option to convert the PDF into PostScript using Ghostscript, Poppler, Cairo, Adobe Reader or Mupdf. The default mode is one which uses Poppler when the printer make is Brother, Minolta or Konica Minolta but Ghostscript for other printer models. If there is a problem with one of these other models it may be beneficial to switch to rendering PostScript from the PDF with the pdftops-renderer option. Details are in /usr/share/doc/cups-filters/README.txt.gz. See also POSTSCRIPT PRINTING DEBUG MODE in the same document. To use Cairo as the renderer:
lpadmin -p <print_queue> -o pdftops-renderer-default=pdftocairo (For an existing queue). lp o pdftops-renderer=pdftocairo <print_job> (On a job-to-job basis).
Problems Printing to a USB Connected Printer
A USB problem can be difficult to track down. The USB backend uses libusb and there is the possibility of a bug in that software. USB to parallel adapters do not always give trouble-free operation. Also, it is not entirely unknown for printers to have bugs in their implementation of the USB standard and, indeed, CUPS has quirks rules to deal with such issues. Options to handle some USB problems have been added to CUPS. Here is an account and analysis of a printing problem solved by the application of a USB quirk.
- Forcing the usb backend into unidirectional mode can work round problems with bidirectional communication. Preventing the reattachment of the usblp kernel module after a job has been printed can prevent some printers cutting off the end of a job or crashing.
- To have only unidirectional USB communication with the printer the print queue should be set up with
lpadmin -p <print_queue> -v <deviceuri> -o usb-unidir-default=true -E -m <PPD_file> (For a new queue). lpadmin -p <print_queue> -o usb-unidir-default=true (For an existing queue). lpadmin -p <print_queue> -R usb-unidir-default (Remove default).
- To not reattach the usblp kernel module after communication with the printer the print queue should be set up with
lpadmin -p <print_queue> -v <device-uri> -o usb-no-reattach-default=true -E -m <PPD_file> (For a new queue). lpadmin -p <print_queue> -o usb-no-reattach-default=true (For an existing queue). lpadmin -p <print_queue> -R usb-no-reattach-default (Remove default).
Problems Printing to a Network Connected Printer
A network printer is a printer device with its own TCP/IP port and connected to the network by ethernet cable or wireless. The printer receives jobs in the networkuri from a CUPS server.
+---------+ Ethernet cable +---------+ +--------+ | |<-------------------->| |<--->| | | Printer | | Network | | Server | | |<====================>| |<===>| | +---------+ Wireless +---------+ +--------+
It is assumed the printer is already on the network with a DHCP assigned or a static IP address. The printer manual should be consulted to ascertain how to set up an ethernet cabled or wireless connection. It is further assumed that security software, for example, a firewall, SELinux orAppArmor, on any client device (desktop computer, laptop, tablet etc) does not degrade the printing or network processes.
Two other assumptions are that a default CUPS installation is installed on the server machine with the cups package and that an examination of its filtering system as described previously on this page has returned nothing of consequence.
- It is not a bad idea to test the filtering system first by getting printing going over a USB connection (if there is one) before attempting a network connection. Likewise, testing a ethernet connection (if there is one) before a wireless one is a reasonable strategy.
The IP address of the printer can often be found from its front panel or from a printed configuration (self-test) page. Running the snmp backend on a client is a quick alternative. The output should include the device-uri (which is likely to be a socket connection) of the device.
Now the ping utilty can be used. With consistent output you should be confident the printing system should be able to locate the printer. Inconsistencies such as many dropped packets or high latencey could mean looking at the network setup. Check for the IP address changing on a regular basis or something blocking the ICMP probes.
ping <IP address>
The printer can be scanned with nmap to discover the printing services it offers. Look for ports 515, 631 or 9100 being open. Not all printers offer the same services. An open port 80 would indicate an embedded web server, a very useful service for making alterations to the printer's configuration with a browser.
nmap <IP address>
The following netcat command tests whether the printer can be reached on port 631:
nc -z <IP_address_or_hostname> 631 && echo ok || echo failed
If the printer cannot be reached it is switched off or has no service on port 631 or there is some basic network problem
The choice of device-uri can be a factor in the quality of the printing experience. A diagnosed problem with the printer implementation of IPP can be tackled by preferring the socket backend; a failure now with printing could point to a network or printer issue, especially as all that is being done is send raw data over TCP/IP to the printer.
A printer which does Bonjour broadcasting can be discovered and identified using avahi-browsed:
avahi-browsed -art | less
will give you the hostname and IPP device-uri for the printer.
Problems Printing with the IPP Backend
In CUPS 1.5.x the IPP backend was rewritten to make it conform more rigorously to IPP standards. Unfortunately, it is not unknown for IPP implementations on some printers and print servers to be buggy and the change resulted in some of them failing to print. As these problems are caused by bugs in the IPP implementations of the hardware and completely IPP-conforming hardware works correctly with the IPP backend of CUPS 1.5.x they were not considered as bugs in CUPS and so not fixed or worked around by CUPS upstream.
A solution is to revert to using the less stringent IPP backend from CUPS 1.4.x for the network device-uri of a print queue. It is provided as ipp14 and offered as an option with lpadmin, the CUPS web interface and system-config-printer.
lpadmin -p <print_queue> -v ipp14://<IP or hostname> -E -m <PPD_file>
Problems with mdns/DNS-SD
Discovery of mDNS (Bonjour) shared printers takes place by default when avahi-daemon is installed. Applications using the GTK dialog subsystem will see these printers in their dialogs. Adding cups-browsed to the system allows other applications and the command line programs also to know about these Bonjour advertised print queues and printers.
iptables --table filter --list | grep mdns
and look at the avahi-browse -art output. Failed to resolve service and an address line which is not in the form xxx.xxx.xxx.xxx would be indications of such a misconfiguration.
A failure to get the print job to a remote printer might also be a router problem or bugs in avahi-daemon. The first could necessitate powering the router off and on; resolving the second is beyond the scope of this wiki page.
The Debian printing system based on CUPS has matured over the years and generally operates reliably with a great number of printers. However, in what is still a developing environment, bugs are to be expected and some of them may visibly affect the printing process. With the large number of packages involved in the printing system it can be perplexing to decide which one a bug applies to. If the report is sent to the cups package there is no harm done.
A user's reaction to an inability to print can vary from viewing it as merely annoying up to intolerable. In spite of the inconvenience it is rarely the case that a failure to produce a satisfactory printout deserves setting the severity level on a bug report to anything greater than important, which is described as
a bug which has a major effect on the usability of a package, without rendering it completely unusable to everyone.
The usual program employed to report a bug is reportbug, which will guide you through the process. In addition to describing your problem there are other data which are useful to give a complete picture of your issue. The printer vendor and model and how it is connected (USB, parallel, network etc) to the machine are often relevant details. Try
/usr/sbin/lpinfo -l -v
for the make and model. Very useful detail can also be obtained from an error_log showing what happens when printing takes place. Compressing a lengthy log with gzip or xz is an option to consider taking. If cups-browsed is the subject of the report, consider activating debug logging for it and attaching the log and your cups-browsed.conf file to the mail.