Tahoe 26.2 breaks printing with PaperCut

Issue

After upgrading to Tahoe 26.2, print queues monitored by PaperCut no longer work. The print queue gets paused, and the jobs fail to print.

This issue was discovered during our internal testing prior to the Tahoe 26.2 public release, and a growing number of our mutual customers have also reported it since then.

Root cause

This appears to be due to changes in the behavior of CUPS Sandbox restrictions, which prevent the backend (and filter) from reading/writing to the PaperCut install folder.

Error messages

  • From syslog.
2025-12-22 16:41:59.283761+1100 0x1daf61   Error       0x0                  0      0    kernel: (Sandbox) Sandbox: papercut(5783) deny(1) file-write-data /Library/Printers/PaperCut/Print Provider/print-provider.log
  • When trying to create a TCP socket from the PaperCut filter.
2025-12-15 19:50:08,403 ERROR: os_tcp_socket_create: getaddrinfo failed: nodename nor servname provided, or not known

Technical details

PaperCut implements print queue monitoring using a CUPS backend (and filter).

CUPS backends and filters run in a security 'sandbox' which limits what they can do (such as file/folder access, create network sockets, and execute sub-processes, etc.).

The PaperCut backend (and filter) relies on some of these operations, so to function correctly, our code updates /etc/cups/cups-files.conf with "Sandboxing relaxed".

Until 26.2, this relaxed mode allowed us to read/write to PaperCut folders, create TCP sockets to communicate with the local PaperCut Application Server, and execute/kill sub-processes.

As an alternative to the relaxed mode, we also tried "Sandboxing off", but that doesn't help either (from CUPS scheduler/conf.h).

typedef enum
{
  CUPSD_SANDBOXING_OFF,			/* No sandboxing */
  CUPSD_SANDBOXING_RELAXED,		/* Relaxed sandboxing */
  CUPSD_SANDBOXING_STRICT		/* Strict sandboxing */
} cupsd_sandboxing_t;

Test code

We can provide a simplified version of our backend that demonstrates the issue if required

Questions

  1. Has the CUPS sandbox relaxing changed? According to the CUPS man pages (cups-files.conf(5)), "Sandboxing relaxed" should still work as before.
  2. If this is the new intended behavior, what are the other options/directives we can use to relax the limitations on CUPS backends and filters?

So, looking at things from our side, I'm not sure. I found one bug on this (r.166518515) about accessing a custom directory ("/Library/<app name>/"), but the analysis of the engineering team is that it isn't a bug in macOS 26.2... because it shouldn't work in macOS 26.0 EITHER.

More specifically, it should only be accessing one of these documented directories: <https://www.cups.org/doc/api-filter.html#SANDBOXING>

"2. Writing of files: pursuant to normal UNIX file permissions, filters and backends can read/write files to the cache directory specified by the CUPS_CACHEDIR environment variable, to the state directory specified by the CUPS_STATEDIR environment variable, to the temporary directory specified by the TMPDIR environment variable, and under the /private/var/db, /private/var/folders, /private/var/lib, /private/var/mysql, /private/var/run, /private/var/spool (except /private/var/spool/cups), /Library/Application Support, /Library/Caches, /Library/Logs, /Library/Preferences, /Library/WebServer, and /Users/Shared directories."

FYI, that does suggest a possible workaround for these issues, which would be to:

  • Have your CUPS component write to an allowed directory (for example, /Library/Application Support/<app name>).

  • If necessary, create a symlink to that location at your current location so that the user-visible behavior remains the same.

  1. Has the CUPS sandbox relaxing changed? According to the CUPS man pages (cups-files.conf(5)), "Sandboxing relaxed" should still work as before.

I'm not sure. I haven't found a specific change, but the problem here is this line from the documentation I reference above:

"The sandbox profile used in CUPS still allows some actions that are not listed above - these privileges will be removed over time until the profile matches the list above."

Sandbox profiles are typically created by including the content of a base "template" profile, which is then modified with any behavior specifically required by that component. The expectation here is that the component-specific profile will define all the behavior it specifically "needs" and then inherit more "basic" behavior from the template. However, that does mean that behaviors can "tighten" if the base template changes, particularly when the component team is expecting the sandbox to tighten (as the CUPS team obviously was). Similarly, I'm not sure what "relaxed" actually defined, but I suspect it was just using one of the more "generic" profiles, which, again, have tended to tighten over time.

  1. If this is the new intended behavior, what are the other options/directives we can use to relax the limitations on CUPS backends and filters?

If this is specifically about the file system, is there any reason you can't shift locations like I outlined above?

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Hi Kevin, thank you for getting back to us.

So, looking at things from our side, I'm not sure. I found one bug on this (r.166518515) about accessing a custom directory ("/Library/<app name>/"), but the analysis of the engineering team is that it isn't a bug in macOS 26.2... because it shouldn't work in macOS 26.0 EITHER.

We have read the man page, and it refers to default sandbox-on behaviour, and not the sandbox-relaxed mode (which we moved to starting from 10.10). As you mentioned, the sandbox-on mode works as advertised in 26.0+. The sandbox-relaxed mode works up to 26.1 and stopped working in 26.2.

FYI, that does suggest a possible workaround for these issues, which would be to: Have your CUPS component write to an allowed directory (for example, /Library/Application Support/<app name>). If necessary, create a symlink to that location at your current location so that the user-visible behavior remains the same.

We are actively working to support sandbox-on mode. However, this is non-trivial for reasons such as:

  • File and folder access: other parts of our product are expecting files to be in specific locations, and we need to create symlinks back from those locations. Some of these files are log files, which involve log rotation, making things more complex.
  • Execute/kill sub-processes: we can no longer kill sub-processes spawned by the backend. We get an EPERM error
  • Network calls from filters: these are no longer possible

In the interim:

  1. Is there anything we can configure or modify in the system to achieve the old behaviour of sandbox-relaxed mode?
  2. If for some reason, we can’t get back to the previous sandbox-relaxed behaviour, is there a way for us to switch off the sandbox?

As of now, we are looking for a quick fix, as we have 100,000s of macOS users who will be unable to print once they upgrade to Tahoe 26.2.

The sandbox-relaxed mode works up to 26.1 and stopped working in 26.2.

So, with a bit more digging, I was able to figure out what's going on here. Basically, as part of a security fix (r.157744252) in macOS 26.2, CUPS was changed to use a fixed configuration, by its config file ("/etc/cups/cups-files.conf"). That's actually what explains this:

As an alternative to the relaxed mode, we also tried "Sandboxing off", but that doesn't help either (from CUPS scheduler/conf.h).

...as CUPS was actually always running at "CUPSD_SANDBOXING_STRICT", regardless of how you configured it.

  1. Is there anything we can configure or modify in the system to achieve the old behaviour of sandbox-relaxed mode?

  2. If for some reason, we can’t get back to the previous sandbox-relaxed behaviour, is there a way for us to switch off the sandbox?

No, I don't think so. The core problem here is that the sandbox configuration itself hasn't actually changed; cupsd is just ignoring any configuration file. I think you can see this directly if you try passing "-s" (which manually specifies a config file). I believe it will print:

cupsd: -s ignored.

...and then proceed to run with the standard, hard-coded configuration (which includes "CUPSD_SANDBOXING_STRICT"). At this point, I don't really see any way around that.

In terms of supporting CUPSD_SANDBOXING_STRICT, am I correct that these two points are the real issues here, not the path limitations?

(1) Execute/kill sub-processes: we can no longer kill sub-processes spawned by the backend. We get an EPERM error.

(2) Network calls from filters: these are no longer possible.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Hi Kevin, Thank you for the clarification.

However, we want to emphasize that the decision to have cupsd ignore one of its main configuration files is a major breaking change.

This is not just a tightening of the sandbox but a major departure from documented CUPS behavior (https://www.cups.org/doc/man-cups-files.conf.html). By ignoring cups-files.conf, macOS disables essential administrative controls required for non-standard printing environments.

As such, we hope the team will reconsider this approach. If a fixed configuration is necessary for the default security posture, there should still be an alternative that allows legitimate, authorized software to operate in “relaxed” mode.

In terms of supporting CUPSD_SANDBOXING_STRICT, am I correct that these two points are the real issues here, not the path limitations?

As we mentioned earlier, it is a combination of all three (file/folder access, sub-process handling, and network calls). We are actively working on modifying our backend/filter to accommodate these restrictions and operate in CUPSD_SANDBOXING_STRICT mode, which requires a careful rewrite of the code to ensure that we don't break current behavior and cause issues for users.

Tahoe 26.2 breaks printing with PaperCut
 
 
Q