Recovering a ZFS Pool That Won't Import on FreeBSD
zpool import shows your pool as UNAVAIL or fails outright. A step-by-step approach to recovering it without panicking or reaching for a backup first.
You run zpool import and either your pool doesn’t show up at all, or it does but reports UNAVAIL or FAULTED. Before assuming data loss, work through ZFS’s own recovery mechanisms — they’re more capable than they might seem in the moment.
Step 1: see what ZFS can actually detect
zpool import
Run without arguments, this scans all attached devices and reports every pool it can find, along with its apparent status, without actually importing anything — a safe, read-only first step.
pool: tank
id: 4519283746192837465
state: UNAVAIL
status: One or more devices are missing from the system.
Step 2: check whether this is genuinely a missing-device problem
UNAVAIL with “one or more devices are missing” means ZFS can’t find enough of the pool’s constituent vdevs to safely assemble it — check camcontrol devlist or geom disk list to confirm which physical disks the system currently sees, and compare against what the pool expects:
camcontrol devlist
zdb -l /dev/da1
zdb -l reads a disk’s ZFS label directly, telling you which pool it belongs to and its role — useful for confirming a disk you thought was part of the pool actually still carries valid ZFS metadata, even if the pool as a whole won’t currently assemble.
Step 3: try importing by numeric pool ID if the name is ambiguous
If multiple pools show similarly or a name collision exists, import by the numeric ID shown in the scan output rather than by name:
zpool import 4519283746192837465 tank
Step 4: if the pool was exported uncleanly, force the import
A pool that wasn’t cleanly exported (a crash, a hard power-off) sometimes needs an explicit force flag, since ZFS is deliberately cautious about importing a pool that might still be in use elsewhere:
zpool import -f tank
Step 5: if recent transactions look suspect, roll back safely
ZFS keeps multiple recent uberblocks (transaction group checkpoints) even after a crash — if the most recent state looks corrupted, you can roll back to an earlier, known-good transaction group without needing a backup at all:
zpool import -F tank
zpool import -FX tank # more aggressive: also discards recent, possibly-corrupt data
-F attempts recovery by rolling back to the last valid transaction group; -FX goes further and is willing to discard more recent data if it can’t otherwise assemble a consistent pool. Run these without -n only once you’ve confirmed via a dry run (-n appended) that the proposed rollback point looks acceptable:
zpool import -nF tank
Step 6: read-only import for data recovery without further risk
If your goal is just to recover files rather than restore full pool functionality, importing read-only avoids writing anything further to a pool that’s already in a fragile state:
zpool import -o readonly=on tank
Why ZFS can usually recover from this
ZFS’s copy-on-write design means old data isn’t overwritten in place — a transaction group commits a new, self-consistent set of pointers, and prior transaction groups’ data often still physically exists on disk until actually reclaimed. That’s precisely what makes -F/-FX rollback recovery possible after many kinds of corruption that would be unrecoverable on a traditional overwrite-in-place filesystem, and it’s worth exhausting these options fully before concluding a pool is genuinely unrecoverable.