What gets checked
Every finding carries a stable rule id (used in suppressions and the JSON output), a severity, the affected service, and the evidence that triggered it.
How to read severities:
-
RED — restore-threatening. If you needed this backup today, it would fail you: nothing is backed up, the backup is stale or empty, or it is unrestorable.
-
YELLOW — hygiene or early warning. Not an emergency, but it will become one if ignored.
Mount drift (dockerHosts)
The classic silent killer: your backup job archives the path the compose file declares, but the container actually writes somewhere else.
| Rule | Severity | Meaning |
|---|---|---|
|
RED |
a declared bind-mount/volume is not mounted in the running container |
|
RED |
mounted, but from a different source path than declared — backups read the wrong place |
|
YELLOW |
the container mounts something the compose file doesn’t declare |
|
YELLOW |
the compose project’s config can’t be resolved on the host (e.g. stacks deployed by an external tool), so drift is uncheckable — one aggregated finding per project |
Stale configs (dockerHosts)
|
YELLOW |
the running container was created from an older compose config than what is on disk — the next restart silently changes behavior |
Database dumps (logicalDbBackups)
|
RED |
a live database container has no dump at all |
|
RED |
newest dump is older than |
|
RED |
the dump file is zero bytes |
|
YELLOW |
the dump is suspiciously small for a real database |
|
RED |
the job’s dump method doesn’t fit the container’s engine (e.g. |
|
RED |
with |
Image backups — Proxmox (pveNodes)
|
RED |
a VM/LXC has no image backup in any configured storage |
|
RED |
newest image backup is older than |
|
RED |
the backup artifact is zero-sized |
|
YELLOW |
a backup exists for a guest that no longer does — usually a rename/migration leftover worth pruning (or a sign the new guest isn’t covered) |
|
YELLOW |
every image backup of a guest lives on non-shared storage of its own node — one disk or host failure takes the guest and all its copies together. Give it a copy that survives the node (PBS/shared storage, or sync the dump dir off the box) |
Off-site sync jobs (offsiteJobs)
Any scheduled rclone (or rclone-style) sync script that logs its runs with
=== <yyyy-MM-dd HH:mm> … sync start === and === sync finished rc=N ===
markers. With rcloneRemote set, the remote’s occupancy also feeds the storage
capacity check (rclone about — not every backend supports it).
|
RED |
the log has no runs at all — the job never ran, or its script doesn’t write the documented markers |
|
RED |
the last run exited non-zero (or never logged a finish line — a killed run) |
|
RED |
no successful run within |
pbsOffsite (below) is the older, single-job PBS-specific flavor of this
check and keeps working; new configs should prefer offsiteJobs.
|
PBS hygiene (pbsMaintenance, pbsOffsite)
|
RED |
the last completed verification reported errors — chunks in the datastore are corrupt |
|
YELLOW |
verify jobs exist but none has ever completed |
|
YELLOW |
last successful verification is older than |
|
YELLOW |
the datastore has no verify job at all — backups are never integrity-checked |
|
YELLOW |
garbage collection has never run on the datastore |
|
YELLOW |
GC hasn’t run within |
|
RED |
the last off-site sync exited non-zero |
|
RED |
no successful off-site sync within |
|
YELLOW |
PBS→PBS sync job(s) exist (auto-discovered) but no sync has ever completed |
|
RED |
the last completed PBS sync did not succeed — the second PBS is behind |
|
RED |
no successful PBS sync within |
|
RED |
a watched |
|
RED |
the newest host backup of a watched host is older than |
File-level backups (fileBackups)
Apply per configured source, across all kinds (restic, borg, kopia, snapper, dir, haos):
|
RED |
the source produced no artifacts at all — empty repo, empty directory, no full backup |
|
RED |
newest artifact is older than the source’s |
|
RED |
the newest artifact is zero-sized |
Restore canary (fileBackups with canaryPath — restic/borg)
Snapshots existing is not the same as backups restoring. Set canaryPath on a
restic or borg source to a small file that must always be in the backup (a config
file is ideal): every audit then streams that file out of the latest snapshot
and counts the bytes on the host — a real end-to-end restore through
decryption and chunk reads, with nothing written anywhere and no content leaving
the machine.
|
RED |
the canary restored as 0 bytes — wrong passphrase, corrupt repo, or the path fell out of the backup. Either way the backup just failed its restore drill |
for borg, give the path as stored in the archive — the leading / is
stripped automatically.
|
SQLite hot-copy detection (sqliteBackupDirs)
Half of selfhosted runs on SQLite (vaultwarden, the arrs, Home Assistant,
paperless), and the classic failure is rsync/cp of a *running app’s data dir:
the copy "succeeds" daily and restores corrupt. SQLite keeps -wal/-shm
files next to a database only while it is open — inside a backup directory they
are proof the copy happened mid-write.
|
RED |
the backup directory contains WAL/SHM files — the database(s) next to them were copied while open and may not restore. Copy with |
ZFS snapshots & replication (zfsReplications)
Sanoid/syncoid-style setups (or any zfs send pipeline) on hosts outside
TrueNAS: the source dataset must keep getting snapshots, and — when a replica is
configured — the replica’s newest snapshot must be fresh too. Both fail quietly
in real labs: the replica keeps its old snapshots and looks fine.
|
RED |
the source dataset has no snapshots at all — the snapshot job never ran here |
|
RED |
newest source snapshot is older than |
|
RED |
the replica dataset has no snapshots — nothing was ever replicated into it |
|
RED |
newest replicated snapshot is older than |
TrueNAS (trueNas)
|
RED |
newest ZFS snapshot is older than |
|
RED |
a cloud-sync task’s last run failed |
|
RED |
a cloud-sync task hasn’t succeeded within |
|
YELLOW |
a configured cloud-sync task is disabled |
|
YELLOW |
a top-level dataset is covered by no cloud-sync task — its data never leaves the box |
Storage & disks (pveNodes, trueNas, smartHosts)
|
RED |
a pool/datastore is not healthy (e.g. DEGRADED) or a disk fails SMART |
|
RED |
usage above the critical threshold — backups may already be silently rejected |
|
YELLOW |
usage above the warning threshold |
|
YELLOW |
last ZFS scrub is too old |
|
YELLOW |
a configured storage is not active |
|
YELLOW |
health could not be determined |
Suppression hygiene (always on)
Suppressions themselves are audited — they can never rot silently:
|
YELLOW |
a suppression passed its |
|
YELLOW |
a suppression points at a host/service that no longer exists |
These two are not suppressible — by design.