Translation(s): none

Techniques to deal with printing problems on the Debian CUPS based printing system.


The aim of this page and the sections of the wiki linked from it is to give some insight on printing with CUPS in Debian 9 (stretch) and later. There are differences in CUPS between the 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 thereby enable effective troubleshooting.

CUPS is the manager of all printing processes via its scheduler, cupsd. It provides only a small number of filters which prepare a print job for sending to a printer:

The majority of filters needed by the Debian printing system come with the cups-filters and cups-filters-core-drivers packages. Some filters essential for Debian systems were not required by upstream CUPS, so were donated to OPenPrinting and now form the basis of the present printing system.

A selection of the filters the cups-filters packages provide is:

When we take the contributions of developers of other free software such as Ghostscript, Poppler, Gutenprint, qpdf 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 upstream and compiled. cups-filters is an OpenPrinting project that interworks with CUPS, but responsibility for its maintenance lies with a separately developed project at OpenPrinting.

The PDF-centric Workflow

Prior to Debian 7 (wheezy), the filtering system was devised to process PostScript files; that is, anfile recognised by CUPS as a known MIME media type was first converted to PostScript before being processed. This PostScript-centric processing is now obsolete on a modern Debian printing system; PostScript hasn't any special place in it.

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. This is a PDF-centric workflow.

The standard chain of filtering would first convert a submitted, known file type to a PDF. After being dealt with by the page management filter, pdftopdf, the output is further processed to produce a file acceptable to the printer, such as PostScript, PCL, Apple raster, PWG raster or some proprietary language.

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 the essence of the PDF-centric workflow.

The CUPS Error Log

The primary tool for debugging 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 programs in other packages such as cups-filters, Ghostscript, Poppler, colord, Tea4CUPS 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 firmware 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):

cupsctl --debug-logging

For all the gory detail:

cupsctl LogLevel=debug2

To turn off debug logging and return to LogLevel=warn:

cupsctl --no-debug-logging

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 LogLevel debug2. cupsd will need a manual restart if this is done:

systemctl restart cups

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[5] is always worth it to see what options are being sent to CUPS.

Further indications of filter and backend behaviour and dispatch to a printer can be sought by searching for:

The error_log may be emptied by root with


For users who rely on sudo to gain root privilege there is:

sudo truncate -s 0 /var/log/cups/error_log

An existing error_log is best emptied first before obtaining the one to be sent to a bug report. error_logs also compress very well with gzip or xz.

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

cupsdisable <print_queue>

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 determined by 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:

cupsenable <print_queue>

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 and restart the cups service:

systemctl restart cups

Set up a print queue that prints to a file rather than sending to a printer. Either

lpadmin -p <print_queue> -v file:/tmp/out.dat -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:

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.

The command

/usr/sbin/lpinfo -v

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

Suppose you have a printer-ready file produced via the filtering system using cupsfilter or which has been captured before being sent to the printer. The command

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 the backend (usb, socket, ipp etc), the connection method (USB or ethernet cable or wireless connection) 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.

cat <printer-ready_file> > /dev/lp0

cat <printer-ready_file> > /dev/usb/lp0

It would be as well to check /dev/lp0 or /dev/usb/lp0 are the correct, usable devices on your system.

Many network-capable printers have an open port 9100. Check with nmap:

nmap <printer_IP_or_host_name>

Then send a printer-ready file to the printer with

nc <printer_IP_or_host_name> 9100 < <printer-ready_file>

Successful printing would imply that there is a problem with the backend.

A user gaining root privileges with sudo would experience failures of the first two of the previous three commands. Substitute commands, which should work, are:

  • sudo sh -c 'cat <printer-ready_file> > /dev/lp0'

  • sudo sh -c 'cat <printer-ready_file> > /dev/usb/lp0'

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.

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).

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

It is not uncommon for a printer to be connected over the network to a CUPS server, particularly when it is a legacy/classic device.| The server receives the print job from a client, processes it, usually using vendor drivers, and sends it off to the printer. A modern device is directly contactable, so the need for such a network printer might be seen as superfluous in that case.

A network printer is a printer device with its own TCP/IP port at 631, 9100 or 515, connected to the network by ethernet cable or wireless and used in conjunction with a CUPS server. The printer receives jobs in the usual way from the CUPS server.

+---------+    Ethernet cable    +---------+     +--------+
|         |<-------------------->|         |<--->|        |
| Printer |                      | Network |     | Server |
|         |<====================>|         |<===>|        |
+---------+      Wireless        +---------+     +--------+


ping <IP_address_or_hostname>

nmap <IP_address_or_hostname>

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 may be switched off or not have a service on port 631 or there is some basic network problem

avahi-browse -rt _ipp._tcp

address =, port = and rp= give its IP address, the services it offers and the resource part of an IPP device-uri respectively. If you have a printer which fits a client's driverless printing system


will give you the hostname and IPP device-uri for the printer.

Problems with mdns/DNS-SD

Discovery of mDNS (Bonjour) shared printers and print queues takes place by default when avahi-daemon is installed. Applications will list these printers and queues in their dialogs. Browsing for mdns/DNS-SD advertised printing services can be done with avahi-browse or its GUI equivalent, avahi-discover.

avahi-browse -rt _ipp._tcp

It is possible for all the queue filters to operate correctly and for the backend to behave impeccably but nothing gets printed. One cause is a firewall misconfiguration. Check with

iptables --table filter --list | grep mdns

and check the avahi-browse output. Failed to resolve service and an address line which is not in the form would be indications of such a misconfiguration.

A failure to get the print job to a remote printer might also be a router or network problem.

See Also