CUPS classes are broken
Describe the bug Starting a couple of years ago, CUPS classes stopped working properly. Now they appear to have stopped working entirely.
To Reproduce Steps to reproduce the behavior:
-
Go to localhost:631 administration page
-
Click on create a class
-
add a printer to the class
-
now try to modify the class. When modifying a class, I get garbage characters rather than the class name and I am unable to add or remove printers from the class
-
using lp, try to print a photo to the class (e.g. lp -d
.jpeg -
the print job shows completed but nothing comes out. Moreover, the same command also fails when I use and actual printer rather than the class.
-
using gwenview, open a photograph then try to send it to a print class.
-
The job shows up in the print queue but never prints. However, the same steps successfully print a photograph when using a printer rather than a class.
Expected behaviour I should be able to create and modify classes. And printing should not depend on whether I am printing to a class or single printer. lp should work for things other than pdfs (which I can print on another machine).
Screenshots If applicable, add screenshots to help explain your problem.
System Information:
- Debian/Trixie (stable, 13) on an AMD64 laptop
- every application I've tried
- CUPS version 2.4.10
Additional context
Hmm, seeing a lot of reports of problems from Trixie-based systems lately… Can you attach the conf files in /etc/cups from your system?
I'm not able to reproduce the garbage GUI issues, although after I modify a printer I am not able to modify it again (just goes back to the main admin page) - doing a little digging to see what the problem might be...
Thanks. The two problems are probably related. I'm wondering if the issue is, at least in part, a character set issue. I note that when I try it from my Forky workstation, I get the same issue. I can bring up the class but cannot modify it. The garbage characters are what I'd expect to see when the wrong char set is used.
The problem affects both my (new installations) trixie laptop and forky workstation, whether connecting to the localhost on my laptop or the (old installation) server.
Further to above, I have now reinstalled 2 inkjet printers on my laptop: the Epson XP-6100 using the driverless driver and an Epson XP-820 using the Epson EscPr v1.8.6-1 driver - there doesn't seem to be a driveress option for this printer. In order to get the second printer into the photo class, I had to delete and recreate the class.
Both printers are set up to default to 4x6 borderless glossy media and both do that when I print to them directly (using lp). However, when I print to the photo class, the XP-820 prints as expected but the XP-6100 shrinks the image and uses a border. While the XP820 doesn't have a print scaling default option, the XP-6100 does and it is set to none.
If I pass the print-scaling=none option, the XP-6100 doesn't shrink to fit but still prints with a border. Unfortunately the media size and type options don't appear to be the same between the two printers (at least in the web interface) so I'm not sure how to specify borderless as an option at the command line.
Moreover, the XP-820 prints without scaling unless I tell it to while I seem to have to tell the XP-6100 to not scale the printing. I would expect that printing to a class would do the same things to all printers in that class but that doesn't seem to be true.
There are no class options I can set for this so I would expect that printing to a class should produce the same output as printing to any of the printers in that class. I don't expect printer classes to bypass the default options for the printers.
However, at least this time, I am getting usable output.
It is not unusual to experience difficulties with certain options when you have two different printers in a class, particularly with two different kinds of drivers.
That said, your XP-820 should work with the IPP Everywhere driver (I used to have this printer and it supports AirPrint and works with the CUPS "everywhere" driver/model), as should the XP-6100. Then at least the options will be (mostly) the same between the printers, which will work better in a class.
Unlike for the XP-6100, there is no IPP driver listed for the XP-820 printer.
However the main issue was the inability to print borderless on the XP-6100 when printing to the class. Why are the default options settings being ignored?
I admit my knowledge of the workings of print classes is rudimentary but I would expect a class to simply select one of the printers then send the lp options to it. It should be indistinguishable from sending the print directly to the printer.
Another problem I'm having is that the XP-6100 is no longer printing from lp. I get a "Print job canceled at printer." message in the CUPS web interface. The error_log just repeats that with the detail Backend ipp returned status 5 (cancel job). However, I can print from a GUI (e.g. gwenview).
I note that the GUI print dialog shows printers shared from my file & print server and also brings back the second XP-6100 instance. However none of those printers show in the web interface nor lpstat and cups-browsed is not running.
@garydale The issue is that "borderless" isn't an option for IPP Everywhere printers, it is a media attribute, specifically, "media-col" with "media-bottom/left/right/top-margin" values of 0. Options set on the class that are not understood by the printer are silently ignored.
As long as you are using IPP to talk to the XP-820, you can use the IPP Everywhere ("-m everywhere" on the command-line, the "IPP Everywhere" driver in the web interface).
Again, you are suggesting that the class is not simply sending the job to a free printer. That seems like a poor design decision compared to simply passing the job as specified to the print queue. It means that a job sent directly to printer behaves differently from one that goes to the class.
The CUPS web interface doesn't have any significant options for classes. All I see are banners and policies. I would expect options sent to a class should be passed on to the printer, not ignored. However, this is not the case for the XP-6100. The printer prints borderless when the image is sent directly to the printer but prints with a border when the print goes through the class. What is the rational for that?
There are no default margin settings for that printer. Still, I would expect that margins would be set based on what the printer can do.
The XP-820 does not have an IPP Everywhere driver on my system. The only options that show up for Epson printers are IPP drivers for some printers (but not the XP-820) or various Epson drivers. I did see (and used) an IPP everywhere option for the just installed XP-8800 I just hooked up but that's rare.
Speaking of the XP-8800, it also shows a USB variant in the Gwenview printer list. This doesn't seem to happen with printers that use drivers.
The XP-8800 is giving me a lot of problems - mostly what seems to be driver communications. Multiple copy prints keep running into problems partway through. Possibly a printer problem.
@garydale The class is simply sending the job to the next available printer, however the job is both the original document data and all of the options (attributes) that you specify. If you have two printers with different sets of options, you will get predictably bad results when you specify an option that is for printer A that gets passed to printer B. If no (or partial) options are specified then the defaults for the printer are used.
How does the XP-820 show up on your system? Is it connected over USB or network?
WRT the XP-8800, I have no experience with that printer but it has AirPrint support and thus should show up with the IPP Everywhere driver as an option. It is also new enough to have IPP-USB support when connected over USB (unlike the XP-820).
WRT KDE's Gwenview, I have never used it and don't know how it supports printing.
Do you understand that I have the same command line for both jobs? When I print to the class, I get a border. When I print to the printer, I don't. The XP-6100 doesn't have a default margins setting in the web interface. It seems to pick them up from specifying borderless media, which makes sense. What is the point of distinguishing between 4x6 and 4x6 borderless media otherwise?
Similarly, when I print to the XP-6100 directly, it doesn't shrink the image. When I print to the class and it goes to the XP-6100 the output shrinks to fit the media, which means including borders so the print is even smaller..
So the question remains, why is it printing differently? I understand that I can specify a very long command line that forces no scaling and zero margins, but why is that even necessary given that the printer seems to understand that when I print to it directly? It looks very much like some processing of the print job is being done before assigning it to a printer.
re. the XP-820: I am connecting all the printers via USB because I will not have access to a router to connect them over wifi for this application..
The 3 printers all have different options in the Epson printer driver list. The XP-820 shows just escpr drivers. The XP-6100 gives me the choice of escpr or driverless when I scroll down to the XP-6100 in the driver list. The XP-8800 shows IPP Everywhere right at the top of the driver list.
re. Gwenview: it's a KDE thing, not a Gwenview peculiarity. Any application should show the same list of printers. I suspect it's Avahi related since I'm seeing printers from my server as well that I don't see in the CUPS web interface (browsed is disabled). The extra USB printers only show up when turned on, while the other printers show up regardless. e.g. the Epson_XP-6100_Series_ shows even while not powered on while the Epson_XP_6100_Series_USB only shows up when the XP-6100 is turned on.
I now have a different problems as well. Starting a little after 2 yesterday, I can no longer print to any local printer from the GUI but can print to them using lp. This has survived multiple reboots and printer restarts, even with or without a USB hub.
To be clear, I did do an apt full-upgrade yesterday but that was before the printing problem started. I was printing to the XP-8800 and had just replaced the paper (to print the second side) when I discovered I could no longer print. The jobs don't show up in the CUPS queue and never se oneem to reach the printer.
I did nothing that should have had any impact on the printers. I was just trying to print multiple copies of a 2-sided document. The only unusual thing was that the XP-8800 twice failed to print all 20 side-ones, requiring a powering down and restart to get it to let me finished printing (I also had to cancel the partial jobs). It took 3 tries, printing 11, 3 and 6 pages, to get all 20 pages printed.
I had to print side 2 from an ssh session on the server - I think lp wasn't working for me either yesterday but it is working today.
@garydale
Do you understand that I have the same command line for both jobs? When I print to the class, I get a border. When I print to the printer, I don't. The XP-6100 doesn't have a default margins setting in the web interface. It seems to pick them up from specifying borderless media, which makes sense. What is the point of distinguishing between 4x6 and 4x6 borderless media otherwise?
The class just collects jobs and forwards them to the next available printer. Any options you pass when printing a job, for example:
lp -dCLASSNAME -o PageSize=4x6.Borderless -o print-scaling=fill FILENAME.jpg
are then passed on to the printer. If the printer's PPD does not list the specified PageSize (or media) then the printer's default media will be used (which is usually not borderless). Similarly, any other PPD option you specify has to exist for ALL printers, otherwise it will only work when printing to a specific printer. Lowercase IPP options (like "print-scaling" above, or using "media" or "media-col" instead of "PageSize") will get mapped to the equivalent PPD option(s), if available.
As I mentioned previously, printer classes are intended for identical or substantially similar printers/drivers. As soon as you start mixing models and drivers you will start having issues because the typical PPD-based options you get from a GUI are different. Photo printers tend to be particularly problematic in this respect... :/
WRT the other issues you are having, I have absolutely no control or resources there - you are better off contacting Debian directly to report the issue and hopefully get some distro-specific support.
There are no media options passed on the command line. The command is either lp -d printer "image to print" or lp -d class "image to print". The first command prints the image full size and borderless while the second prints the image with a border and shrunk to fit when the image goes to the XP-6100 (but not when sent to the XP-820).
The default options are set using the CUPS localhost:631 interface. The XP-6100 has a print-scaling option in the CUPS interface. It is set to "none". Interestingly, the XP-8800 doesn't have that option but the same command line also prints a 4x6 borderless photo with no scaling. However, even though the default media is 4x6 borderless, when I print to the class, it wants to print the 4x6 photo to letter-size paper on the XP-8800.
Interestingly, when I try to print to the class using Okular, it shows the default properties as 4x6 borderless with zero margins.
I think the common factor is that the Epson printers all have 2 media trays with tray 1 usually holding letter or A4 and tray 2 usually holding photo paper. In my case however, the XP-6100 has problems with tray 2 so I loaded photo paper into tray 1 instead. However the driverless drivers seem to want to print to tray 1 instead of of the tray containing the media specified as the printer default.
Moreover, as previously mentioned printing to the class seems to ignore the other defaults for the printers in the class that use the driverless drivers.
re. the other issues: the behaviour is bizarre. I don't think CUPS is entirely innocent though. It's what ultimately controls the printing so it should play nice with Avahi & KDE.
Again, I have just lost the ability to print using lp after printing to the class and getting the image printed on letter-size paper. However I now have it back for printing from the GUI. This is definitely a CUPS issue as all I did was turn the printer off then back on again.
Still hoping to see a solution for the issue of CUPS not using the printer defaults when printing to a class. Your suggestion of specifying media sizes doesn't appear to be workable as not all printers in the class all use the same media size names. In particular, the XP-820 uses the sizes 4X6FULL and T4X6FULL instead of the ipp name of 4x6.Borderless.
The issue of the difference in drivers / options would not exist if printing to a class simply used the default options set for the actual printer assigned to the job instead of ignoring them. All 3 printers are set to print a high quality 4x6 borderless image on glossy 4x6 photo paper. This used to work when there were only printers with drivers. I don't understand why it is an issue when 2 of the printers use ipp. Why should ipp ignore the CUPS printer options?
To make matters worse, when I use the PageSize option for ipp printers, things get really bad:
lp -d photo -o PageSize=4x6.Borderless -o print-scaling=none photoname
The XP-820 now insists on printing from tray 1 while the other 2 printers don't print at all. I get the message "Print job canceled at printer." when print goes to the XP-8800 while I merely get no output when it goes to the XP-6100.
When I remove the PageSize option, the XP-820 output is what I want (4x6 borderless with no scaling). The other 2 printers still don't print.
lpstat -a EPSON_XP-6100_Series_ accepting requests since Tue 02 Dec 2025 03:27:59 PM EPSON_XP-820_Series accepting requests since Tue 02 Dec 2025 03:26:35 PM EPSON_XP-8800_Series accepting requests since Tue 02 Dec 2025 03:27:57 PM photo accepting requests since Thu 27 Nov 2025 03:59:22 PM
Here's the photo class:
photo photo-quality inkjet printers /printers/EPSON_XP-6100_Series_, /printers/EPSON_XP-820_Series, /printers/EPSON_XP-8800_Series Idle
cups-browsed is not running but both the XP-6100 and XP-8800 are showing phantom USB versions when I look at the printer list from a GUI app. However the panel on the XP-8800 does show the job being cancelled (no, I didn't cancel it) so that job at least is reaching the correct printer. Note that I can print to the XP-8800 and the XP-6100 from a GUI app.
The issue seems to be a fundamental error in the processing sequence for classes. For a printer, the sequence is:
- get the defaults for the printer
- apply the command line options
- send to the destination
For a class they should be:
- identify which printer to use
- use the first process to send the job to that printer
Instead you seem to be treating classes as a printer and using the first process against the class. The output is then sent directly to the printer with no further processing - i.e.:
- use the first process to set the options for the class
- send the output as is to a printer.
This explains all the symptoms I am seeing.
As I said originally, CUPS classes are broken. There appears to be a fundamental misunderstanding of the proper role of a class. CUPS is treating a class as a pseudo-printer instead of as a collection of printers. This doesn't even allow printers of similar vintage from the same manufacturer to work properly.
Perhaps if everything was using ipp and if all printers implemented it the same way, it wouldn't matter. But with printers having different features, including different media sources (trays), it makes a huge difference to the output you actually get.
If the CUPS people can't produce reasonable code to handle classes, ripping out their code and replacing it with a simple round-robin printer selector that uses process 2 above would be better than what you have. Or you could get a little fancier and poll the printers to find the next free one.
In my case, I can do what I need in the bash script I use for my application by setting a persistent variable then incrementing it after printing each photo, resetting it when it exceeds the number of printers in my array of printer names. Then I use the variable as an index into the array for the lp statement. This is not ideal but it works whereas the CUPS classes simply don't.