3.8 KiB
UniFi Backup Restore Pitfalls (v10.0.162, Jul 2026)
The Core Problem
UniFi .unf backup files are encrypted BSON. They cannot be read by:
zipfile(Python) — throwsBadZipFilebsondump(MongoDB) — reports "invalid BSONSize"mongorestore— can't parse the encryption
The ONLY way to restore a .unf is through the UniFi ace.jar restore command, which decrypts and imports the data into a running MongoDB.
Failed Restore Approaches
1. CLI: java -jar ace.jar restore <file> (FAILED)
Error: NoSuchBeanDefinitionException: No qualifying bean of type 'com.ubnt.service.system.status.o0OO'
Root cause: ace.jar restore instantiates the FULL Spring application context, not just a MongoDB connection. It requires all UniFi service beans to be available. Running it in isolation (even with just MongoDB) fails because the Spring context expects the complete application environment.
Attempted workarounds that also failed:
- SIGSTOP the running UniFi Java process, then run restore → Spring context collision
- SIGKILL the process → entrypoint restarts it
- One-off Docker container with just mongod + ace.jar → same Spring bean missing
2. API: POST /api/s/default/cmd/backup (FAILED)
Error: {"meta":{"rc":"error","msg":"api.err.NoSiteContext"}}
Root cause: In UniFi 10.x, even with valid authentication (unifises cookie from /api/login → {"meta":{"rc":"ok"}}), the backup/restore API endpoints require a site context. /api/self returns admin details correctly, but any site-scoped endpoint fails.
Prerequisites that were configured correctly and still failed:
- Admin with
super_site_permissions: ["super"],is_super: true,super_site_role: "super" - Privilege records with ObjectId
admin_idandsite_idfor both "super" and "default" sites - Role:
SUPER_ADMIN, permissions:["ALL"]
Attempted endpoints that all return NoSiteContext or Invalid:
/api/s/default/cmd/backup(withcmd: "list-backups"orcmd: "restore")/api/s/super/cmd/backup/api/s/default/cmd/system/api/system/backup/api/system/backup/list/api/system/backup/restore
What DOES Work
Fresh deploy + re-adopt devices
When the controller is deployed fresh (no backup restore), devices that were previously adopted to another controller will try to inform but fail with "inform decryption failed." To re-adopt:
- SSH into each UniFi device
- Run:
set-inform http://<controller-ip>:8080/inform - The device appears in the controller UI as "pending adoption"
- Click "Adopt" in the UI
Backup restore via the UI Setup Wizard
On FIRST boot of jacobalberty/unifi, the setup wizard at https://<host>:8443 offers a "Restore from Backup" option. This is the only reliable path to restore a .unf file on v10.x.
What to check before deploying to avoid this
- Always export a
.unfbefore decommissioning the old controller - Store the
.unfin S3 — don't rely on it surviving on the server - Note the old controller version — major version jumps (9.x → 10.x) add restore risk
- Document device SSH credentials — needed for re-adoption if restore fails
Dual-Storage Architecture Trap
The jacobalberty/unifi Docker image uses TWO storage locations that can diverge:
Host /opt/unifi → Container /config (bind mount: system.properties, certs, old backups)
Docker volume → Container /unifi (anonymous: MongoDB data, live backups, sites)
The container symlinks /usr/lib/unifi/data → /unifi/data. When running a one-off container for restore, you MUST use --volumes-from to access the anonymous volume. Simply bind-mounting /opt/unifi:/config only gives you the stale config files, not the live MongoDB.
To inspect the anonymous volume path:
docker inspect unifi-controller --format '{{json .Mounts}}' | python3 -m json.tool