FreeBSD administrator providing live chat help with lpd queue permissions

Joe B.

Reviewed for technical accuracy

Specialities: FreeBSD & BSD printing, lpd(8) / lpr(1) queues, CUPS vs LPD migrations, /var/spool/lpd permissions, jails & NFS print servers, printer filters & drivers

Fix “FreeBSD lpd queue drops jobs — permissions” — stop lpd losing print jobs, repair /var/spool/lpd ownership, and keep FreeBSD printers working

Technician avatar Technician
Hey there — we can definitely help when a FreeBSD lpd queue drops jobs or accepts them and then silently discards everything. Nine times out of ten, when lpd(8) loses print jobs like this, it comes down to permissions and ownership on /var/spool/lpd and the printer device, not the printer itself.

To get you to a fix quickly, I need to narrow this down a bit: which FreeBSD version are you on, and what is the name of the queue in /etc/printcap? When a user runs lpr, does lpq show the job briefly and then it disappears, or does it never show at all? Finally, do you know who owns /var/spool/lpd and the specific queue directory — root, daemon, or someone else?
Customer
This is a FreeBSD 13.2 box. I’m using the base lpr/lpd printing system, not CUPS. In /etc/rc.conf I have lpd_enable="YES", and there’s a single queue called laser in /etc/printcap. When users run lpr, lpq shows the job for a second or two, then the lpd queue drops the job and nothing comes out of the printer. No obvious error on the client side, just “job printed”. That’s why I suspect it might be some FreeBSD lpd permissions issue.
Technician avatar Technician
Thanks, that’s exactly the sort of detail we need.

On FreeBSD, the classic pattern when an lpd queue drops jobs immediately is:
• lpr successfully writes the control/data files into /var/spool/lpd/laser.
• lpd(8) wakes up, tries to read the data file or write to the device or filter.
• Because of wrong file permissions or ownership, lpd can’t access something it needs, logs an error in /var/log/lpd-errs, and cleans up the job — so it vanishes from lpq and never hits the printer.

The usual suspects are:
• The queue directory in /var/spool/lpd is owned by root:wheel and mode 755, but lpd runs as user daemon, so it can’t fully manage the files.
• The spool directory or log file has modes that don’t match what the Handbook expects (typically daemon:daemon with 770 or similar).
• A custom input filter script in /var/spool/lpd/laser/filter has the wrong execute bit or ownership, so lpd can’t run it and just discards the job.

First step is to look at /var/log/lpd-errs and the exact permissions on /var/spool/lpd and the laser subdirectory — that usually tells us why the FreeBSD lpd print queue is dropping jobs.
Customer
OK, checked that. /var/spool/lpd is owned by root:wheel, mode 755. The queue /var/spool/lpd/laser is also root:wheel with 755. When I submit a job, I can see cfA* and dfA* files appear briefly, then they disappear when lpd drops the job. The printer itself is a network laser connected over TCP 9100 via a simple if filter script in printcap. That filter is a shell script owned by root and executable.
Technician avatar Technician
Perfect, that lines up with the classic problem.

By design, the FreeBSD lpd daemon runs as the user daemon after it starts. The Handbook’s examples for LPD queues assume that:
• /var/spool/lpd and each queue under it (like /var/spool/lpd/laser) are owned by daemon or another dedicated printing user.
• Those directories are usually mode 770 or similar, so daemon can create, rename, and remove the cf* and df* files freely.
• The lock, status, and errs files are also writable by daemon.

Right now, since everything is root:wheel 755, lpr (running as your user) can still create files, but lpd can hit permission denied when it goes to manipulate them, or when it tries to append to errs. Lpd interprets that as a broken job, logs what it can, and cleans up — which looks like the lpd queue losing jobs.

The fix is usually to follow the FreeBSD LPD permissions layout: make the spool directories and log owned by the account that lpd uses (normally daemon) with group write and no world access, then restart lpd.
Customer
That makes sense, but this box also runs some jails and shared services, so I’m cautious about changing ownerships system-wide. What’s the minimal set of permission changes you’d recommend to stop the FreeBSD lpd queue from dropping jobs without opening things up too much? Just the specific queue directory and log file?
Technician avatar Technician
Totally fair to be cautious — we only need to touch the LPD spool tree, nothing else.

Minimal, sane changes I normally use when a FreeBSD lpd queue drops jobs because of permissions:
1) Change ownership of the base spool directory and the specific queue to daemon:
chown daemon:daemon /var/spool/lpd /var/spool/lpd/laser
2) Tighten the modes so only lpd and its group can touch them:
chmod 770 /var/spool/lpd /var/spool/lpd/laser
3) Make sure the log and lock files inside the queue (errs, status, lock) are also daemon:daemon and at least mode 660.
4) Leave your if filter script owned by root:wheel but make sure it’s executable (chmod 755) so daemon can run it.

After that, restart lpd with service lpd restart, submit a test job with printf 'test\n' | lpr -P laser, and watch /var/log/lpd-errs and lpq. In most cases, these ownership changes alone stop the lpd queue from silently discarding jobs.
Customer
I applied those changes and restarted lpd. Now jobs stay in the queue longer, but occasionally they still disappear with no output. The printer is a network device, and I’m forwarding the data with nc in the filter. /var/log/lpd-errs shows lines like “laser: daemon: cannot read dfA123hostname: Permission denied” and sometimes “write: Permission denied” to the device. So the FreeBSD lpd queue still drops some jobs due to permissions, just not all of them.
Technician avatar Technician
Those log lines are super helpful — they confirm this is still a permissions problem in the lpd spool directory or filter path, not a driver issue.

Things to double-check when FreeBSD lpd loses jobs with “Permission denied”:
• Inside /var/spool/lpd/laser, verify new cfA* and dfA* files end up owned by daemon after lpd picks them up. If they’re left owned by the submitting user with restrictive modes, lpd might not be able to re-open them.
• Ensure your filter script doesn’t create temp files or FIFOs in a directory that daemon can’t write to. A lot of custom filters still use /tmp or a private directory with the wrong mode.
• If you’re using a device file (parallel or USB) instead of raw TCP, check that /dev/lpt0 or the relevant /dev/ugen* node has group permissions that allow daemon to write.

As a quick test, run, as root: sudo -u daemon cat /var/spool/lpd/laser/dfA* right after a job arrives. If that fails, we know the data file permissions in the lpd queue still aren’t correct.
Customer
Another detail: when I submit a job as root, it prints every time. When normal users run lpr, that’s when the lpd queue drops the job. The dfA* files created for user jobs are owned by that user with mode 600 until lpd tries to handle them. I guess that’s why daemon can’t read them. Is there a recommended way in FreeBSD to handle user permissions in /var/spool/lpd so lpd can read jobs but users can’t mess with each other’s files?
Technician avatar Technician
You’ve nailed it — that root-vs-user difference is a classic sign that lpd can’t read user-owned data files.

The traditional FreeBSD approach is:
• The spool directory itself (/var/spool/lpd/laser) is owned by daemon and has the set-gid bit with group daemon (for example, chmod 2770).
• Users are allowed to create files there, but thanks to the directory’s group and mode, lpd can still read them even when their default umask is restrictive.
• Alternatively, you can relax the default umask used when lpr writes the spool file, but most people leave that alone and rely on the directory ownership and set-gid behaviour.

In practice, I’d set:
chown daemon:daemon /var/spool/lpd/laser
chmod 2770 /var/spool/lpd/laser
so new cf* and df* files inherit group daemon, making them readable by lpd even if the user’s umask is 077. That usually stops FreeBSD lpd from dropping user jobs while root jobs succeed.
Customer
One more twist: this FreeBSD print server runs inside a jail, and the spool directory is a nullfs mount from the host. Could that impact lpd permissions? The host has slightly different uid/gid layouts, but the jail sees daemon as uid 1. Jobs are still disappearing in the jailed lpd even after I tweak the modes.
Technician avatar Technician
Yes, jails and nullfs can absolutely complicate a FreeBSD lpd queue that drops jobs.

A few jail-specific checks:
• Confirm that the uid and gid for daemon inside the jail match the ownership on the underlying directory on the host. If they don’t, what looks like daemon:daemon inside the jail may actually be someone else on the host.
• Make sure the nullfs mount is not exported with root-squash type semantics (more common with NFS, but worth verifying), which could strip privileges from the jail’s daemon user.
• If the jail has its own devfs ruleset, confirm that any printer device you use is actually writable from inside the jail and not clamped down by the rules.

In short, for lpd in a jail the permissions must line up in three places: host filesystem, nullfs mount, and jail user IDs. Once those all agree, the lpd queue permissions problems tend to disappear.
Customer
That explains why this broke after we rebuilt the server. On the old bare-metal host, the FreeBSD lpd printing setup worked for years, but after moving to a new ZFS host plus jail, that’s when the lpd queue started dropping jobs. So it’s probably the changed ownerships and jail mappings, not lpd itself. I’d still like a clear checklist of what to verify so we don’t miss anything.
Technician avatar Technician
Exactly — lpd itself hasn’t changed much in decades; what changes is the environment around it: ZFS datasets, jails, new default umask values, and stricter permissions from the security team.

Quick reasons why a FreeBSD lpd queue that used to work now drops jobs:
• New host or jail uses different uid/gid for daemon, so existing /var/spool/lpd ownerships no longer match the running daemon.
• Spool directories were recreated by root with 755 modes instead of the group-writable 770 that lpd expects.
• The path in /etc/printcap (sd=/var/spool/lpd/laser, lf=/var/log/lpd-errs) doesn’t match the actual directories after a migration, so lpd logs errors to a different place than you’re checking.
• Filters or helper scripts were copied from an old system but lost their execute bit or ended up on a filesystem with different mount options.

Once we standardize those pieces, lpd usually goes back to what it’s good at: quietly spooling text or PostScript without drama.
Customer
Got it. For this server I just want the FreeBSD lpd queue to stop dropping jobs and behave predictably again. Can you summarize the steps we should follow to fix lpd permissions and spool directories, and maybe help double-check our printcap and jail setup one-on-one?
Technician avatar Technician
Absolutely — here’s the practical recipe I use whenever a FreeBSD lpd queue drops jobs because of permissions:

1) Confirm that sd= and lf= in /etc/printcap point to the real spool directory and log file (for example, /var/spool/lpd/laser and /var/log/lpd-errs), then make sure lpd is enabled with lpd_enable="YES".
2) Set ownership on /var/spool/lpd and each queue directory to the user that lpd runs as (usually daemon) and apply chmod 2770 so new jobs inherit the correct group and permissions.
3) Fix the errs, lock, and status files inside the queue to be writable by daemon, and ensure any filter scripts listed as if= in printcap are executable.
4) If you’re running lpd inside a jail or over NFS/nullfs, verify that uid/gid mappings and filesystem ACLs line up between host and jail so daemon really has access to /var/spool/lpd and the printer device.

If you’d like, I can review your FreeBSD lpd configuration, spool directory permissions, and jail mounts step by step from screenshots or command output. Open the chat and we’ll get your lpd queue stable so print jobs stop disappearing.

Quick answer: the accepted fix

Accepted fix when a FreeBSD lpd queue drops jobs: verify /etc/printcap points to the correct /var/spool/lpd/<queue> directory and lpd-errs log, change spool directories to be owned by the lpd user (typically daemon) with modes like 2770, ensure data and control files are readable by that user, and restart lpd. In jails or on NFS, make sure uid/gid mappings and filesystem permissions match so lpd can access the queue and device.


Why your FreeBSD lpd queue drops jobs because of permissions

When a FreeBSD lpd print queue keeps dropping jobs, the issue is rarely the printer hardware. The Berkeley printing system relies on a specific layout and ownership for /var/spool/lpd, the queue directories, and log files. If those directories are owned by root:wheel with restrictive modes, but lpd runs as the daemon user, the daemon may not be able to reopen data files, run filters, or update lpd-errs. Lpd then removes the job from the queue as failed, which looks like the queue is silently losing jobs. Fixing ownership and modes so the lpd user can fully manage the spool directory is the key to stopping dropped print jobs on FreeBSD.

How to verify a FreeBSD lpd queue after fixing permissions

Once you adjust lpd spool directory permissions, test the setup before relying on it. Restart the daemon with service lpd restart, then submit a simple text job like printf "LPD test\n" | lpr -P laser. Watch lpq -P laser to confirm the job appears and disappears only after printing. At the same time, tail /var/log/lpd-errs to make sure there are no new “Permission denied” messages. Try printing both as root and as a normal user; if both succeed and the lpd queue no longer drops jobs, your permissions and ownerships are in good shape.

FreeBSD lpd queues — quick tips for permission problems

Before you blame the printer or filters, check the ownership and mode of your lpd spool directories.

Quick path: confirm that lpd_enable="YES" is set and printcap points to the right sd= and lf= paths → ensure /var/spool/lpd and its subdirectories are owned by the lpd user (daemon) with group-writable modes like 2770 → make sure errs, lock, and status are writable by that user → verify filter scripts are executable and any device nodes or network helpers are reachable. These small changes resolve most cases where a FreeBSD lpd queue drops jobs due to permissions.

Disclaimer: This information is AI-generated and intended for general guidance only. Always review the official FreeBSD Handbook, lpd(8) and printcap(5) manual pages, and your organization’s security policies. For advice tailored to your specific FreeBSD version, jails, and printers, please consult a verified expert on Whizz-Tech before making significant changes.


Getting Started Is Easy

Ask for help, 24/7

Members enjoy round-the-clock access to 12,000+ verified Experts, including FreeBSD and Unix administrators who troubleshoot lpd print queues, /var/spool/lpd permissions, and printer filters every day.

Expert will respond in minutes

We match you with an Expert who specializes in FreeBSD lpd queues, printcap configuration, and permissions inside jails, so you can stop chasing dropped jobs and get reliable printing again.

Save time & money

Avoid stalled batch jobs, duplicate prints, and frustrated users. We’ll help you fix FreeBSD lpd permission errors, document the correct spool layout, and keep your BSD print server stable long-term.

FAQ

Why does my FreeBSD lpd queue accept jobs and then drop them?

On FreeBSD, if an lpd queue accepts jobs and then they disappear, it usually means the daemon could not read the data files, run the filter, or update its log because of incorrect permissions on /var/spool/lpd or the queue directory. Lpd logs the failure in lpd-errs and removes the job from the queue instead of leaving it stuck.

What permissions should /var/spool/lpd have on FreeBSD?

The FreeBSD Handbook recommends that /var/spool/lpd and each printer’s queue directory be owned by the lpd user (typically daemon) and not by root. Common settings are ownership daemon:daemon with directory modes like 2770, so lpd can create, read, and remove cf*/df* files while normal users submit jobs via lpr.

How can I debug lpd permission problems?

First, check /var/log/lpd-errs for “Permission denied” or “cannot open” messages. Then verify the sd= and lf= entries in /etc/printcap, inspect ownership and modes of /var/spool/lpd and its subdirectories, and test reading dfA* files as the daemon user. Adjust permissions until lpd can manage the queue without errors.

Can I run FreeBSD lpd inside a jail or on NFS?

Yes, but you must be careful with uid/gid mappings and filesystem permissions. When running lpd in a jail or over NFS/nullfs, ensure the lpd user inside the jail matches the ownership of the spool directory on the host, and that mount options do not prevent writes. Otherwise the queue may drop jobs even though everything looks correct from inside the jail.

Sources

Matt Verified Icon
Matt ● replies in < 1 min
Technician Expert
⭐⭐⭐⭐⭐ Trusted by 27,000+ customers
Avatar
Alex · Expert's Assistant