Prove your Proxmox backups restore, not just that they’re stored.
PBP (PVE Backup Proofing) restores each guest’s newest backup into an isolated network, boots it, checks it from the inside, and records the verdict on the backup itself.
“Verified” does not mean that it will function when restored.
Proxmox Backup Server’s verify job is good at what it does: it proves the backup’s data is intact. It can’t tell you whether the guest will boot, whether its filesystem mounts read-write, or whether its services come up.
An untested backup is not a backup. If you’ve come from VMware and miss Live Recovery’s test recovery, or from XCP-ng and Xen Orchestra’s backup verification, you know what that proof is worth. PBP brings it to Proxmox, building on PBS rather than replacing it: trust, but verify.
Restore, boot, check, record.
PBP is a small daemon that runs on a schedule, in Docker or from a .deb package.
Each run works through your guests like this:
-
01
Pick
The newest backup of each guest, across your PBS storages. Guests whose last proof is oldest, or who were never proven, go first.
-
02
Protect
Mark the backup protected, so pruning can’t remove it mid-proof.
-
03
Restore
Restore it as a temporary guest in a VMID range you reserve for PBP, tagged
pbp. -
04
Make it safe
Move every network card onto an isolated bridge, turn off start-on-boot, and remove host passthrough. Anything that can’t be made safe is never started.
-
05
Boot
Start the copy and wait for it to come up.
-
06
Check inside
Look at the running system from the inside: failed services, a read-write root filesystem, and the checks you define.
-
07
Clean up
Destroy the copy and its disks, and put the backup’s protection back the way it was.
-
08
Record
Write the verdict into the backup’s notes in Proxmox, and send one summary through Proxmox’s own notification targets.
What it checks inside.
-
Linux
systemd guests: no failed units, a read-write root filesystem, and service profiles for common software such as PostgreSQL, MariaDB, nginx, Docker and SSH.
-
Windows VMs
Through the QEMU guest agent: every automatic-start service that should be running is running.
-
Alpine and Gentoo containers
OpenRC services in the runlevel, instead of systemd.
-
Your own checks
Per-guest services that must be active, ports that must be listening, and commands that must succeed.
Some units fail by design on an isolated network. Ignore lists cover them →
Five verdicts, one that counts against a backup.
| Verdict | Meaning | Says something about the backup? |
|---|---|---|
PROVEN | Restored, booted, all checks passed | Yes: good |
FAILED | The restore failed, the boot failed, or a check failed | Yes: bad |
BOOTED | The guest started, but PBP couldn’t look inside (for example, a VM without the guest agent) | Partially |
SKIPPED | Not attempted: excluded, a template, not enough space or RAM, already proven, or the run’s deadline reached | No |
ERROR | A PBP or node problem, such as an SSH or API failure, or a guest that couldn’t be made safe | No |
Only FAILED indicts a backup. SKIPPED and ERROR mean “not proven yet”, and BOOTED means “starts, but not looked inside”.
Real results, real value.
A green backup job tells you the data was copied. A PBP run tells you whether it restores, boots and starts its services, before anyone is waiting on it.
-
Fewer surprises at the disaster recovery review
Your recurring DR review starts from evidence, not hope. PBP has already restored, booted and checked your guests’ newest backups, and each verdict is written on the backup itself. The meeting is about the ones that failed, or couldn’t be proven yet, and why.
-
Catch what only breaks on a restart
Some hosts run for months without a reboot, so a service that won’t come back up stays hidden until the day you need it. PBP boots a copy of each guest’s newest backup on a schedule, so the problem shows up in a run summary, not in an outage.
-
Prove your services come up, not just the guest
Booting is the start. For what’s enabled in the guest, PBP checks that it really works: PostgreSQL answers, nginx is listening, Docker is up. Add your own per-guest checks, and a guest only passes when the services you rely on do.
gitea-runner.service had failed. Found by PBP, not by an outage.Built to run next to production.
-
Never logs in as root
A Proxmox API token with a narrow role, and SSH only as an unprivileged
pbpuser locked to one helper command. -
Copies are isolated before they boot
Every network card moves to the isolated bridge, which PBP checks really is isolated. Passthrough is removed and start-on-boot is off.
-
Backups are left as they were
Apart from the verdict line in its notes. A backup is protected while it’s being proven, and its original protection setting is put back afterwards.
-
Cleans up after itself
Teardown always runs, and a janitor removes anything a crashed run left behind. PBP only touches guests in its own VMID range.
-
Checks capacity first
A guest is skipped, not restored, when the node lacks the space or RAM for it.
-
Can stay off production nodes
Run PBP on a separate host, and proof on a dedicated Proxmox node instead of a production one.
Security model: what PBP can touch, and what a stolen key could and couldn’t do →
Coming from VMware or XCP-ng?
PBP covers the proving side of backup recovery. Here’s where it lines up with what you had, and where it doesn’t.
Comparable to
-
VMware Live Recovery’s test recovery
Bring recovered systems up in an isolated network to prove they work, without touching production.
-
XCP-ng and Xen Orchestra’s backup verification
Restore a backup, boot it and check it, then throw the copy away.
Not a tool for
Instant or live restore
Running a VM straight from backup storage.
Replication
Keeping a standby copy of guests on another host.
Failover
Switching production to another site.
Get started.
Install the .deb on the host that will run PBP, check that the release is signed by the
maintainer, and let pbp setup walk you through the rest.
Requirements
- Proxmox
- Proxmox VE 9.0 or newer, and Proxmox Backup Server 4.0 or newer
- On the node
- A restore storage, an isolated bridge, a free VMID range,
sudo, and a root shell once for setup - PBP host
- Docker with Compose, or Debian (amd64 or arm64). For production, a separate host outside the cluster it proofs
v=0.8.2; a=$(dpkg --print-architecture)
base=https://github.com/Breadth-Security/PVE-Backup-Proofing/releases/download/v$(echo "$v" | tr '~' -)
curl -fsSLO https://raw.githubusercontent.com/Breadth-Security/PVE-Backup-Proofing/main/allowed_signers
grep '^pbp-release' allowed_signers | cut -d' ' -f3- | ssh-keygen -lf - | grep -qF SHA256:HzEvo7r8x719x/XzBa5JDQFsFdsw79kNXIdaUt2a7a8 && # the key must match the fingerprint below
curl -fsSLO "$base/pbp_${v}_${a}.deb" && curl -fsSLO "$base/SHA256SUMS" && curl -fsSLO "$base/SHA256SUMS.sig" &&
ssh-keygen -Y verify -f allowed_signers -I pbp-release -n pbp-release -s SHA256SUMS.sig < SHA256SUMS &&
sha256sum -c SHA256SUMS --ignore-missing && # any failed check stops here
sudo apt install "./pbp_${v}_${a}.deb"
sudo pbp setup --deb # prints two lines to run on the node; paste the reply back
sudo systemctl start pbp
Check the signature
Releases are signed with PBP’s SSH signing key (ED25519). Its fingerprint is
SHA256:HzEvo7r8x719x/XzBa5JDQFsFdsw79kNXIdaUt2a7a8
Compare it with a second source before you trust it: the Verified badge on the
v0.8.2 tag on GitHub shows the same key. The verify step must print
Good "pbp-release" signature.
Prove your backups.
PBP is open source and built in the open. Download a release and point it at a lab or a quiet node first. Questions, bugs and ideas are welcome.
A quick check keeps the address away from spam bots.
- License
- Apache-2.0
- Current release
- v0.8.2
- Status
- Releases available; pre-1.0