A workstation's off-site backup had been failing every single night for five nights straight — with zero alerting anywhere. Here's how it was found by accident, the obvious suspect that turned out to be completely unrelated, the actual root cause, the fix, and how it got real monitoring afterward so this class of bug can't hide again.
A common two-layer btrfs backup pattern: local snapshots on every system change (via snapper),
plus a nightly incremental btrfs send / btrfs receive off-box to a NAS (via
btrbk), run as a systemd oneshot service on a timer.
volume /mnt/btrfs-root
subvolume @
snapshot_name root
target nas.example.com:/volume1/backups
subvolume @home
snapshot_name home
target nas.example.com:/volume1/backups
failed state produces zero proactive signal on its
own. Nothing surfaces it in normal use — no email, no desktop notification, nothing. This one had
been broken for 5 consecutive nights before an unrelated question ("should X also be backed up?") prompted a
check of what was actually covered, which is what turned up
systemctl status btrbk.service reporting failed.
This machine had a known-flaky secondary NVMe drive that had dropped to an unresponsive state before (twice), and had done so again around the same time — the natural first suspect. Before assuming anything, the actual physical layout got checked directly rather than guessed at:
findmnt /mnt/btrfs-root
lsblk -o NAME,SIZE,MODEL,MOUNTPOINT
The backed-up filesystem lived entirely on a completely different, healthy drive. Kernel/journal logs for the flaky drive showed only errors scoped to that device's own health checks — no PCIe-bus-level symptoms, nothing touching the actual backup source. The dropped drive was not the cause — confirmed, not assumed, before moving on.
The real error, from the service's own log:
ERROR: Failed to send/receive subvolume: .../root.20260718T0300 [.../root.20260717T0937] -> nas:.../root.20260718T0300
ERROR: ... attribute 12 requested but not present.
ERROR: Error while resuming backups, aborting
The sending side was running a modern btrfs-progs (v7.x); the receiving NAS was running an
ancient, vendor-bundled version (v4.x) that isn't independently upgradable. Something in that night's
incremental delta produced a send-stream command using a newer timestamp attribute the old receiver's parser
simply didn't understand, aborting the transfer partway through.
A partial, corrupted subvolume from the interrupted transfer was still sitting on the NAS target, confirmed via:
btrfs subvolume show /volume1/backups/root.20260718T0300
It had a Received UUID already assigned — proof the stream got partway through writing before
it died, not that it failed instantly.
Rather than trying to identify the exact file operation that triggered the incompatible stream command, the pragmatic fix was a one-time full, non-incremental resend of the current state — full sends use a simpler stream encoding than incrementals and bypass the specific broken delta entirely:
btrfs send /mnt/btrfs-root/.snapshots/root.LATEST | \
ssh nas.example.com "btrfs receive /volume1/backups/"
Verified success by checking the receiving end got a real Received UUID with the
readonly flag set — not just "the command didn't error." Then cleanup: deleted the corrupted
partial subvolume on the NAS, and deleted the handful of local snapshots that had never successfully synced
and were now superseded by the fresh baseline, so the backup tool wouldn't keep trying (and failing) to walk
through them on future runs. A manual run afterward completed with zero errors — the incremental chain was
healthy again going forward.
Fixing the immediate failure doesn't prevent the next silent one. The real fix was adding this host to the
existing Checkmk monitoring stack, so a failed systemd unit generates a real alert instead of
waiting for someone to notice.
This particular workstation runs a distro with no native .deb/.rpm packaging, so
the agent went on manually from Checkmk's own generic Linux artifacts rather than a packaged install — every
modern Checkmk site serves these directly, no special access needed:
# the plain agent data-collector script, and the TLS registration/transport binary
curl -s https://checkmk.example.com/site/check_mk/agents/check_mk_agent.linux -o /usr/bin/check_mk_agent
curl -s https://checkmk.example.com/site/check_mk/agents/linux/cmk-agent-ctl.gz | gunzip > /usr/bin/cmk-agent-ctl
chmod 0755 /usr/bin/check_mk_agent /usr/bin/cmk-agent-ctl
# systemd units: a socket-activated agent + a TLS controller daemon on 6556/tcp
# (copy the exact unit files from any already-working packaged install on the
# same Checkmk version with `systemctl cat check-mk-agent.socket [email protected]
# cmk-agent-ctl-daemon.service` — they're portable, no distro-specific content)
cmk-agent-ctl register --hostname my-workstation --server checkmk.example.com \
--site mysite --user automation --password <secret> --trust-cert
6556/tcp same as any packaged
install, but if this is the only host in the fleet running its own firewall (most VMs/containers rely on
network-level segmentation instead), that port needs an explicit allow rule — otherwise the monitoring server's
fetch just times out with no useful error on either side. Scope the rule to the monitoring server specifically
rather than opening the port broadly:
ufw allow from <checkmk-server-ip> to any port 6556 proto tcp
The instinct is to configure a specific, individually-named check for the one service you care about. Before
doing that: Checkmk's stock "Systemd Service Summary" check — discovered automatically on every Linux host,
zero configuration required — already treats any unit entering failed state as critical
by default, and names the specific failed unit(s) in its output. A oneshot backup service's normal healthy
resting state is inactive, not active, so this doesn't false-positive between runs
— only a genuine failed state trips it.