Guide: restoring a Proxmox backup from BorgBackup
This guide follows Backing up Proxmox with BorgBackup, monitored with Borg-UI. It starts from the Borg repository already filled by the daily backup and explains how to get the data back, from a single container up to losing the whole host.
A backup that has never been restored is just a hypothesis. The number one tip of this whole guide: do a test restore now, on a small container, while you’re not in a hurry.
Before you start
The commands use these names, which you should adapt to your setup:
| What | Example value |
|---|---|
| Repository | /mnt/nas-backup/borg-proxmox |
| Dump archives | proxmox-YYYY-MM-DD_HH-MM |
| Configuration archives | pve-config-YYYY-MM-DD_HH-MM |
| Dump folder on the host | /var/lib/vz/dump |
| Staging folder for the restore | /mnt/nas-backup/restore |
You need two things: the repository passphrase and, for disaster recovery, the repository key too (with repokey it’s inside the repository itself, but it’s still worth having an export off the host).
For convenience, load the passphrase into the environment. The backup reads it from a root-only file:
source /etc/borg-backup.env
export BORG_REPO=/mnt/nas-backup/borg-proxmox
If the passphrase isn’t available in that file, export it by hand with export BORG_PASSPHRASE='...' or let Borg prompt for it.
The lock. Borg holds a lock on the repository while someone is using it. If the backup script is running (in my case it starts at 08:00), the command may wait or fail. Wait for it to finish. Use
borg break-lockonly if you’re sure no process is working on the repository.
1. Find out what’s in the repository
List all archives:
borg list "$BORG_REPO"
Only the dumps, or only the configuration:
borg list "$BORG_REPO" --glob-archives 'proxmox-*'
borg list "$BORG_REPO" --glob-archives 'pve-config-*'
Look inside an archive and find the dump you need (ID 103 is an example):
borg list "$BORG_REPO"::proxmox-2026-11-06_08-00 | grep 'vzdump-.*-103-'
Paths inside the archive have no leading slash: the dump /var/lib/vz/dump/vzdump-lxc-103-...tar.zst shows up as var/lib/vz/dump/vzdump-lxc-103-...tar.zst. Copy the exact name from the output.
You can see the same information in Borg-UI by opening the repository and browsing the archives: handy for finding the right date before switching to the command line.
2. Extract only what you need
Don’t extract a whole archive: it contains every dump and can weigh hundreds of GB. Extract just the file you need.
Where to extract. Pick a volume with free space, not the host’s root filesystem (pve-root): it’s small, and filling it up puts Proxmox in trouble. The NAS or a large datastore is fine.
First a dry run, to check that the command does what you think:
borg extract --dry-run --list "$BORG_REPO"::proxmox-2026-11-06_08-00 \
var/lib/vz/dump/vzdump-lxc-103-2026_11_06-08_00_01.tar.zst
Then the real extraction:
mkdir -p /mnt/nas-backup/restore
cd /mnt/nas-backup/restore
borg extract "$BORG_REPO"::proxmox-2026-11-06_08-00 \
var/lib/vz/dump/vzdump-lxc-103-2026_11_06-08_00_01.tar.zst
The file appears in /mnt/nas-backup/restore/var/lib/vz/dump/.
Alternative: mount the archive. If FUSE is available you can mount the archive as if it were a folder and copy what you need:
mkdir -p /mnt/borg
borg mount "$BORG_REPO"::proxmox-2026-11-06_08-00 /mnt/borg
ls /mnt/borg/var/lib/vz/dump/
# ...copy what you need...
borg umount /mnt/borg
3. Restore a container (LXC)
Container dumps are vzdump-lxc-ID-...tar.zst files.
pct restore 203 /mnt/nas-backup/restore/var/lib/vz/dump/vzdump-lxc-103-2026_11_06-08_00_01.tar.zst \
--storage local-lvm
Key points:
- Use a new ID (here
203, while the original is103). That way you don’t overwrite the existing container and can check that the restore works before replacing it. - Check the network before starting it: if the container uses a static IP, running the copy alongside the original causes an address conflict. Keep the copy stopped or change its IP. The
--uniqueoption ofpct restorealso generates a new MAC address for the copy. - If you want to replace the original, stop it and restore onto the same ID with
--force, which overwrites the existing container:
pct stop 103
pct restore 103 /mnt/nas-backup/restore/var/lib/vz/dump/vzdump-lxc-103-2026_11_06-08_00_01.tar.zst \
--storage local-lvm --force
Start it and check:
pct start 203
pct status 203
4. Restore a virtual machine (QEMU)
VM dumps are vzdump-qemu-ID-...vma.zst files.
qmrestore /mnt/nas-backup/restore/var/lib/vz/dump/vzdump-qemu-102-2026_11_06-08_00_01.vma.zst 202 \
--storage local-lvm
The same rules as for containers apply: a new ID for testing (202), --force to overwrite, and watch out for duplicate IPs and MACs if you start the copy while the original is running. Here too, --unique gives the copy a new MAC.
qm start 202
qm status 202
5. Restore the Proxmox configuration
The pve-config-* archives contain /etc/pve, /etc/network/interfaces, /etc/hosts and /etc/hostname.
Extract into a temporary folder and copy by hand only the files you need:
mkdir -p /root/pve-restore
cd /root/pve-restore
borg extract "$BORG_REPO"::pve-config-2026-11-06_08-00
ls etc/pve/lxc etc/pve/qemu-server
cat etc/pve/storage.cfg
Examples of targeted recovery:
# a container's configuration, if you lost the .conf file
cp etc/pve/lxc/103.conf /etc/pve/lxc/103.conf
# storage definitions
diff etc/pve/storage.cfg /etc/pve/storage.cfg
Don’t extract directly over /etc/pve. It’s the Proxmox cluster filesystem (pmxcfs), not a regular folder: overwriting it with a batch of files can break the host. Compare, copy only what’s needed, and leave alone the files you don’t know.
6. Disaster recovery: the host is gone
Scenario: the system disk died or the host won’t boot, but the NAS with the repository is intact.
Reinstall Proxmox VE on the hardware (same major version, if possible) with the same hostname and the same IP address.
Restore networking and the NAS mount. Recreate the NAS mount at
/mnt/nas-backupwith the same path (NFS or CIFS, depending on how it was set up), because the script and the storages expect that mount point.Install Borg (
apt install borgbackup). Check the version withborg --version: the repository is in Borg 1.x format, so you need a 1.x release (ideally the same as or newer than the one used for the backup). Borg 2 uses a different format and can’t open a 1.x repository directly.Get the passphrase and the key. With
repokeythe key is in the repository, so the passphrase is enough. If you exported the key instead:borg key import /mnt/nas-backup/borg-proxmox /path/to/borg-key-backup.txtCheck that the repository opens:
export BORG_PASSPHRASE='...' borg list /mnt/nas-backup/borg-proxmox | tailRecreate the storages with the same names the backups used (for example
local-lvm), using thestorage.cfgfrom the most recentpve-config-*archive.Restore VMs and containers one by one, as in sections 3 and 4, from the latest dump, with the original IDs (the new host has no conflicts).
Recover the configuration files you need (section 5), without overwriting
/etc/pvewholesale.Reinstall the backup script, the
/etc/borg-backup.envfile with600permissions, and the cron line.Check the first backup after the restore, by watching the log and making sure the new archive shows up.
7. Check regularly that the backups are healthy
Check the repository integrity (structure, not data) outside the cron window:
borg check --repository-only "$BORG_REPO"
With a large repository (hundreds of GB) the full data check takes a long time:
borg check --verify-data "$BORG_REPO"
Run it now and then, when you can leave the NAS busy for hours. Both commands hold the lock, so don’t run them while the backup is running.
The most important check, though, is the practical one: every so often, restore a small container with a new ID, start it, check that it works, then delete it:
pct destroy 203
rm -rf /mnt/nas-backup/restore
Quick checklist
- Repository passphrase off the host (password manager)
- Repository key exported with
borg key exportand stored elsewhere - Extract to a volume with free space, not the host root
- New ID for test restores
- Never extract directly over
/etc/pve - At least one test restore done
-
borg checknow and then
Useful references
- Borg documentation:
borg extract,borg mount,borg check,borg key - Proxmox documentation:
vzdump,pct restore,qmrestore