A workstation's off-site backup had failed every night for five nights straight, with zero alerting anywhere. Here is how it was found by accident, the obvious suspect that turned out to be unrelated, the real root cause, the fix, and the monitoring added afterward so this class of bug cannot hide again.
A common two-layer btrfs backup pattern. Local snapshots on every system change, via snapper.
Plus a nightly incremental btrfs send and 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. An unrelated question, "should X also be backed up?",
prompted a check of what was actually covered. That is what turned up
systemctl status btrbk.service reporting failed.
This machine has a known-flaky secondary NVMe drive. It had dropped to an unresponsive state twice before, and had done so again around the same time. The natural first suspect. Before assuming anything, I checked the physical layout directly rather than guessing:
findmnt /mnt/btrfs-root
lsblk -o NAME,SIZE,MODEL,MOUNTPOINT
The backed-up filesystem lived entirely on a different, healthy drive. Kernel and journal logs for the flaky drive showed errors scoped to that device's own health checks. No PCIe-bus-level symptoms. Nothing touching the 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 ran a modern btrfs-progs, v7.x. The receiving NAS ran an ancient
vendor-bundled v4.x that is not independently upgradable. Something in that night's incremental delta
produced a send-stream command using a newer timestamp attribute the old receiver's parser did not
understand. That aborted the transfer partway through.
A partial, corrupted subvolume from the interrupted transfer was still sitting on the NAS target. Confirmed with:
btrfs subvolume show /volume1/backups/root.20260718T0300
It already had a Received UUID assigned. Proof the stream got partway through writing before it
died, rather than failing instantly.
I did not try 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 broken delta entirely:
btrfs send /mnt/btrfs-root/.snapshots/root.LATEST | \
ssh nas.example.com "btrfs receive /volume1/backups/"
Verify success by checking the receiving end got a real Received UUID with the
readonly flag set. Not by "the command didn't error". Then clean up. Delete the corrupted
partial subvolume on the NAS. Delete the handful of local snapshots that never synced and are now superseded
by the fresh baseline, so the backup tool does not 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.
Fixing the immediate failure does not 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 workstation runs a distro with no native .deb or .rpm packaging, so the agent
went on by hand from Checkmk's own generic Linux artifacts. 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 plus 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 are portable, with 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. If this is the only host in the fleet running its own firewall, and most VMs and containers rely on
network-level segmentation instead, that port needs an explicit allow rule. Without one the monitoring
server's fetch times out with no useful error on either side. Scope the rule to the monitoring server 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. Look
at what you already have first. Checkmk's stock "Systemd Service Summary" check is discovered automatically
on every Linux host with zero configuration. It already treats any unit entering failed
state as critical, and names the failed units in its output. A oneshot backup service's healthy resting state
is inactive, not active, so it does not false-positive between runs. Only a genuine
failed state trips it.