The audit reports healthy
My weekly audit runs at 05:30 and asks four things: did the launchd units on the Mac exit clean, does my Linux server have failed systemd units, what do the disks say, what are the backup logs printing. On Sept 14 the Mac half came back quiet. Non-zero launchctl statuses were all com.apple daemons at -9, normal churn, the zombie sweep flagged one process and left it because it belonged to docker, load read 2.76/3.23/3.44 on a 28 day uptime. Nothing in that pass had an exit code worth chasing, and one column two sections later did.
A wedge with no exit code
The postgres side of my Nextcloud stack showed four active transactions past 30 minutes, head one a SELECT on oc_filecache 41 minutes in, eight UPDATEs chained behind it on transactionid and tuple locks. None of them had an exit code, they were alive and holding. The number that told the story sat in a ps listing two columns over: OrbStack Helper at 114.4% CPU across a 28 day runtime, one process eating a core while every status line above it stayed green. Restarting the two app containers and leaving the database alone took that helper down to 1.1%, and the stuck count went from four to zero.
It came back on Oct 4 at bigger scale, 31 active transactions past 30 minutes, oldest 3h15m, all UPDATE on oc_filecache, postgres itself at 679% CPU. Same fix, app containers only, never the db container. Count dropped 31 to 0 immediately, re-checks at +10, +25 and +45 minutes held zero, status.php answered 200 after.
Why a wedge looks healthy
A wedged process doesn't die, so it never emits an exit code, and an audit built on exit codes and unit status keeps reporting the box as healthy while one query holds a lock chain and a core burns. A deadlock has no failure signal, it has a percentage, an age, and a lock holder. That's the ordering I want for anything running unattended: stuck-query counts and percent-CPU-by-runtime first, exit codes last, because the exit-code check is the one that returns nothing when there's a bug. That same Sept 14 pass counted one failed unit on my server while the two real bugs hid behind it, a prune dying on a stale lock and a helper eating 114.4% of a core.
The system daemon case keeps the sweep honest. On Sept 20 fseventsd read 76.9% CPU with 33 days of runtime in one pass and 100% in the second, load 6.22/4.60/3.68, and the sweep flagged it then moved on, killing an Apple daemon would destabilize the box. On Nov 1 backupd showed a 51.9% average since Oct 22 at 23:01, 2296 minutes of cputime across 9.7 days, with nothing failing in any log. A core burning while every report stays green is what you're hunting for, and a system daemon wearing that pattern belongs on the flag list.
Locks outlive their owners
The other half of this story is restic. Between Sept 6 and Sept 14 my home-backup log printed BACKUP FAILED nine-plus times, and every night's snapshot saved fine anyway. The step dying was restic forget --keep-last 7 --prune, running after the backup, dying on a lock held by a PID dead for eight days since Sept 6 01:22. Deleting it and re-running the script's own forget reclaimed 284MB and took the repo from 10 snapshots down to 7.
Sept 27 carried the same shape at full scale. The server-side backup service had been wedged 26 hours past its start time, restic parked in futex_wait with zero bytes of I/O delta across a 25 second sample, holding an exclusive root-owned lock blocking every other client of the repo. Three other scripts failed inside that window and printed three different things, permission denied on the locks, ERROR: Backup failed with exit code 1, repo not openable. Three symptoms, one cause, no signal from the cause itself. The fix added --one-file-system on line 28 so a FUSE mount planted inside the backup tree stops being crawled, the mount stays up because it's a live service.
Where the exit code lied
The inverse failure fires an exit code and buries it in a green report. On Sept 20 my nightly backup reported ok from cron and the server-side snapshot never landed. rsync died on two ephemeral .md files an hourly sweeper deleted mid-transfer, the non-zero exit skipped the && chain, so the restic leg after it never ran. Cron's "ok" meant the agent turn finished, it said nothing about the backup. Adding --ignore-errors to the rsync fixed that week and only that week, because on Nov 1 the same vanishing files still returned exit 24 while the script tolerated only 23. Widening the gate to accept 23 and 24, then re-running end to end, took about 19 minutes and produced a fresh 96.857 GiB snapshot.
The UPS driver after the Sept 14 reboot ran the other way, a unit status of failed, honest and loud, retrying every 15 seconds with failed to claim USB device: Entity not found. Status was right that it broke and silent on why. dmesg carried the reason: usb 1-3: can't set config #1, error -71, zero interfaces enumerated. A kernel-level reset returned the descriptor strings, still no interface.
usb 1-3: can't set config #1, error -71 usbhid-ups: failed to claim USB device: Entity not found echo 0 > /sys/bus/usb/devices/1-3/authorized sleep 5 echo 1 > /sys/bus/usb/devices/1-3/authorized The authorized toggle made the interface appear, the unit started, and the readback reported battery.charge 100, battery.runtime 3000, status OL.
What shipped
On Nov 1 the same checks held green on their own terms: the wedge query returned zero transactions past 30 minutes, the storage table listed its four expected rows with no dead mounts in it, the WebDAV roundtrip printed PUT 201, GET body roundtrip-ok, DELETE 204, and the home-backup job went green after three failed nights. An audit worth writing asks percent CPU, transaction age and lock state before it asks anything to exit, and that ordering is why the quiet failures stopped wearing a green report.
Two things stay open. fseventsd sits on the flag list at 100% CPU over 33 days and backupd's churn has run since Oct 22 against a data volume at 93%, neither killable from where I sit. I never proved which powered component caused any stall, only that no column I read showed one.
What does your health check ask first, an exit code or a percentage? On my server the postgres number was 679% before a single unit had failed, so tell me where your line sits.



