I've noticed a behavior that may have been going on for awhile, but only recently was brought to my attention. When a user prints from a client with a "browsed" remote cups queue, and that user then intentionally cancels the print job at the printer, the client computer will begin retrying that print job repeatedly. Also, for reasons I have yet to determine, each retry also appends the job to the existing job (doubling the number of copies on every retry attempt).
I've observed that this only occurs on clients with printers browsed from a remote cups server, where that server is then connected to the printer via ipp/ipps. If the same client is connected directly with the printer ( ipps:// ), this does not occur. My guess is that this occurs where implicitclass is used.
I've tested this with a few combination of debian-based linux systems I have on hand, and a few models of HP enterprise network printers, and one model of small-office Canon network printer. I set up a debian Trixie system as the "server" (offering to the shared queues to be browsed by clients) and an ubuntu 26.04 system as the "server". As clients, I tried a few different versions of debian-based client (ubuntu 24/26, Mint, debian). All seemed to exhibit this behavior.
To see this behavior:
- Set up a Linux cups "server". Set settings in cupsd.conf that allow clients to browse the shared printers
Listen 0.0.0.0:631 and Allow all in the <Location /> directive block
- Create a printer in this cups instance, connected with ipp/ipps, using the IPP everywhere driver. Share the printer
- Set up a client with cups-browsed, configured to browse the cups queue from the server. For example, in cups-browsed.conf, a
BrowsePoll directive pointing to the IP address of the server
- Print a document from the client to this shared printer, such that you have to time manually cancel it while it is in progress.
End of client job log for a job printing from the client directly to the printer (ipps):
D [25/Aug/2026:19:02:24 -0500] [Job 314] job-password-encryption-supported 1setOf keyword none,sha2-256
D [25/Aug/2026:19:02:24 -0500] [Job 314] printer-state-message textWithoutLanguage
D [25/Aug/2026:19:02:24 -0500] [Job 314] ---- end-of-attributes-tag ----
D [25/Aug/2026:19:02:24 -0500] [Job 314] ATTR: auth-info-required=none
E [25/Aug/2026:19:02:24 -0500] [Job 314] Print job canceled at printer.
D [25/Aug/2026:19:02:24 -0500] [Job 314] Set job-printer-state-message to "Print job canceled at printer.", current level=ERROR
D [25/Aug/2026:19:02:24 -0500] [Job 314] PID 1067977 (/usr/lib/cups/backend/ipps) stopped with status 5.
W [25/Aug/2026:19:02:24 -0500] [Job 314] Backend ipps returned status 5 (cancel job)
D [25/Aug/2026:19:02:24 -0500] [Job 314] time-at-completed=1787702544
I [25/Aug/2026:19:02:24 -0500] [Job 314] Job canceled at printer.
D [25/Aug/2026:19:02:25 -0500] [Job 314] Unloading...
End of a client job log for a job printing to a browsed remote queue:
D [25/Aug/2026:18:57:25 -0500] [Job 313] cfFilterExternal (ipp): multiple-document-handling-supported 1setOf keyword separate-documents-uncollated-copies,separate-documents-collated-copies
D [25/Aug/2026:18:57:25 -0500] [Job 313] cfFilterExternal (ipp): operations-supported 1setOf enum Print-Job,Validate-Job,Create-Job,Send-Document,Cancel-Job,Get-Job-Attributes,Get-Jobs,Get-Printer-Attributes,Hold-Job,Release-Job,Pause-Printer,Resume-Printer,Purge-Jobs,Set-Printer-Attributes,Set-Job-Attributes,Get-Printer-Supported-Values,Create-Printer-Subscriptions,Create-Job-Subscriptions,Get-Subscription-Attributes,Get-Subscriptions,Renew-Subscription,Cancel-Subscription,Get-Notifications,Enable-Printer,Disable-Printer,Hold-New-Jobs,Release-Held-New-Jobs,Cancel-Jobs,Cancel-My-Jobs,Close-Job,CUPS-Get-Default,CUPS-Get-Printers,CUPS-Add-Modify-Printer,CUPS-Delete-Printer,CUPS-Get-Classes,CUPS-Add-Modify-Class,CUPS-Delete-Class,CUPS-Accept-Jobs,CUPS-Reject-Jobs,CUPS-Set-Default,CUPS-Get-Devices,CUPS-Get-PPDs,CUPS-Move-Job,CUPS-Authenticate-Job,CUPS-Get-PPD,CUPS-Get-Document,Restart-Job
D [25/Aug/2026:18:57:25 -0500] [Job 313] cfFilterExternal (ipp): ---- end-of-attributes-tag ----
D [25/Aug/2026:18:57:25 -0500] [Job 313] ATTR: auth-info-required=none
E [25/Aug/2026:18:57:25 -0500] [Job 313] cfFilterExternal (ipp): Print job canceled at printer.
E [25/Aug/2026:18:57:25 -0500] [Job 313] cfFilterExternal (ipp): Backend (PID 1067687) stopped with status 5
D [25/Aug/2026:18:57:25 -0500] [Job 313] Set job-printer-state-message to "cfFilterExternal (ipp): Backend (PID 1067687) stopped with status 5", current level=ERROR
D [25/Aug/2026:18:57:25 -0500] [Job 313] cfFilterExternal (ipp): Logging (PID 1067688) exited with no errors.
D [25/Aug/2026:18:57:25 -0500] [Job 313] cfFilterChain: Backend completed with status 1.
E [25/Aug/2026:18:57:25 -0500] [Job 313] cfFilterChain: Backend (PID 1067686) stopped with status 1
D [25/Aug/2026:18:57:25 -0500] [Job 313] Closed the pipes for back and side channels
E [25/Aug/2026:18:57:25 -0500] [Job 313] Job processing failed.
D [25/Aug/2026:18:57:25 -0500] [Job 313] PID 1067683 (/usr/lib/cups/backend/implicitclass) stopped with status 1.
W [25/Aug/2026:18:57:25 -0500] [Job 313] Backend implicitclass returned status 1 (failed)
I [25/Aug/2026:18:57:25 -0500] [Job 313] Job held for 300 seconds since it could not be sent.
Some brief glancing at the code seems to point to the different error codes returned from the ipp backend and the implicitclass backend. In main cups source (https://github.com/OpenPrinting/cups/blob/e119e5c84d88679fae61b63f789b584af89d8ba8/scheduler/job.c#L3247), the ipp backend returns error values which are handled there. Note that error 5 as seen in the logs is "CUPS_BACKEND_CANCEL", which leads the the job being actually cancelled.
However, when implicit class returns from a job canceled at the printer at this point, it will return "1" instead of "5" which leads to it being retried (presuming that the error policy is retry-job or retry-current-job). At (
|
retval = cfFilterChain(fd, nullfd, fd != 0 ? 1 : 0, &filter_data, |
) implicitclass calls cfFilterChain which eventually calls the ipp backend as a
filter, which, when it receives the "error" of being canceled at the printer, is then handled by filter.c in the libcupsfilters repository at (
https://github.com/OpenPrinting/libcupsfilters/blob/b95e5a4703d5ccf5129ffe49b6646bd7fbce91cf/cupsfilters/filter.c#L1544 ) which turns this ipp backend return into "status = 1" at (
https://github.com/OpenPrinting/libcupsfilters/blob/b95e5a4703d5ccf5129ffe49b6646bd7fbce91cf/cupsfilters/filter.c#L1568 ), which then implicit class turns into a return of "1" back to the cups job scheduler (
).
IN general, a workaround to this is to set the error policy to "Abort job" instead of retrying. However, should this be fixed? Without enough knowledge of the connected pieces of cups, I'm not sure where the best place to fix this would be.
I've noticed a behavior that may have been going on for awhile, but only recently was brought to my attention. When a user prints from a client with a "browsed" remote cups queue, and that user then intentionally cancels the print job at the printer, the client computer will begin retrying that print job repeatedly. Also, for reasons I have yet to determine, each retry also appends the job to the existing job (doubling the number of copies on every retry attempt).
I've observed that this only occurs on clients with printers browsed from a remote cups server, where that server is then connected to the printer via ipp/ipps. If the same client is connected directly with the printer ( ipps:// ), this does not occur. My guess is that this occurs where implicitclass is used.
I've tested this with a few combination of debian-based linux systems I have on hand, and a few models of HP enterprise network printers, and one model of small-office Canon network printer. I set up a debian Trixie system as the "server" (offering to the shared queues to be browsed by clients) and an ubuntu 26.04 system as the "server". As clients, I tried a few different versions of debian-based client (ubuntu 24/26, Mint, debian). All seemed to exhibit this behavior.
To see this behavior:
Listen 0.0.0.0:631andAllow allin the<Location />directive blockBrowsePolldirective pointing to the IP address of the serverEnd of client job log for a job printing from the client directly to the printer (ipps):
End of a client job log for a job printing to a browsed remote queue:
Some brief glancing at the code seems to point to the different error codes returned from the ipp backend and the implicitclass backend. In main cups source (https://github.com/OpenPrinting/cups/blob/e119e5c84d88679fae61b63f789b584af89d8ba8/scheduler/job.c#L3247), the ipp backend returns error values which are handled there. Note that error 5 as seen in the logs is "CUPS_BACKEND_CANCEL", which leads the the job being actually cancelled.
However, when implicit class returns from a job canceled at the printer at this point, it will return "1" instead of "5" which leads to it being retried (presuming that the error policy is retry-job or retry-current-job). At (
cups-browsed/backend/implicitclass.c
Line 386 in 04b26c8
cups-browsed/backend/implicitclass.c
Line 403 in 04b26c8
IN general, a workaround to this is to set the error policy to "Abort job" instead of retrying. However, should this be fixed? Without enough knowledge of the connected pieces of cups, I'm not sure where the best place to fix this would be.