What Do the Four ZFS Pool States Mean?
ZFS tracks pool health at the vdev level. Each vdev reports one of four states: ONLINE, DEGRADED, FAULTED, or UNAVAIL. The pool state is the worst state among its top-level vdevs.
ONLINE
All vdevs are healthy. No errors detected. Normal operation. No action needed.
DEGRADED
One or more vdevs have lost a member but can still serve data using redundancy (raidz parity or mirror copies). The pool is operational but running without full fault tolerance. Safe to read from; assess before writing.
FAULTED
A vdev has lost too many members to maintain data integrity. raidz1 tolerates one drive failure; losing two or more exceeds its parity. raidz2 tolerates two failures; losing three or more exceeds its parity. The pool cannot serve I/O. Do not write to the remaining drives.
UNAVAIL
ZFS cannot open the device at all. The drive may be disconnected, failed, or its device path may have changed (common after controller or cabling changes). Check physical connections and device paths before assuming hardware failure.
Example: In a raidz2 vdev, if one member fails (UNAVAIL) the vdev transitions to DEGRADED while still serving data. If a second member then reports checksum errors and ZFS marks it FAULTED, the vdev has consumed both units of parity margin. One more failure transitions the pool to FAULTED. At that point there is a narrow window to image the remaining drives before redundancy is exhausted.
How Do You Safely Export and Import a ZFS Pool?
Exporting a ZFS pool flushes pending writes and marks the pool as cleanly closed. Importing reads the on-disk metadata and reconstructs the in-memory state. Both operations are safe when done correctly, but import with the wrong flags can overwrite recoverable metadata.
- 1.
zpool export poolnameflushes all pending transaction groups to disk and marks the pool as exported. This is the cleanest way to take a pool offline. Only works if the pool is in ONLINE or DEGRADED state. - 2.
zpool import -o readonly=on poolnameimports the pool in read-only mode, preventing the OS from writing metadata updates. However, NEVER run this on drives suspected of physical failure. Even a read-only import forces massive random read activity across the array to traverse the ZFS metadata tree, which will destroy a drive with failing read heads. Always perform a sector-by-sector clone of every member drive using dedicated imaging hardware first, and only attempt to import the cloned images. - 3.
zpool import -f poolnameforce-imports a pool that was not cleanly exported. ZFS replays the intent log (ZIL) to recover acknowledged synchronous writes not yet committed via a transaction group sync. This writes to the drives and may advance the on-disk state past a recoverable point. - 4.If the pool will not import at all, do not use
-frepeatedly. Image the drives and work from copies.
Example: If a QNAP NAS loses power during a scrub and its drives are connected to a separate Linux workstation, zpool import may show the pool as available but not exported. Running zpool import -o readonly=on mounts the pool without writing anything to the member drives, allowing data to be copied to a new destination before deciding whether to repair or rebuild the pool.
What Are the Risks of zpool clear?
zpool clear resets error counters on a vdev and tells ZFS to retry I/O. If the errors were transient (a loose cable), this brings the vdev back online. If the drive is failing, clearing errors masks the problem and allows further corruption.
- 1.ZFS tracks read errors, write errors, and checksum errors per device. When error counts exceed internal thresholds, ZFS marks the vdev as FAULTED.
- 2.
zpool clear poolnameresets these counters to zero and retries failed I/O. If the drive responds, ZFS marks it ONLINE again. - 3.If the underlying drive has bad sectors or a failing head, the errors will return. In the meantime, ZFS will write new data to the faulty drive, and that data may be lost when the errors recur.
- 4.The next scrub will detect the corruption, but by then the pool may have advanced past the last consistent transaction group.
Rule: Only run zpool clear if you have identified and fixed the root cause (reseated a cable, replaced a controller, resolved a power issue). If the drive itself is failing (check SMART), replace it instead of clearing errors.
Example: If a drive shows checksum errors caused by physical damage and zpool clear is used to reset the counters, the errors disappear temporarily. As new data is written to those damaged sectors in the interim, it is stored with corruption. A later scrub reveals recurring errors, but by then single-parity protection like raidz1 may be unable to repair sectors that were written with bad data.
How Do ZFS Transaction Group Rollbacks Work?
ZFS uses copy-on-write for all data and metadata. Every write goes into a new location on disk, and the old data remains until the space is reclaimed. Transaction groups (TXGs) are batched commits that advance the pool to a new consistent state. If the latest TXG is corrupted, you can roll back to a previous one.
- 1.ZFS flushes a new TXG to disk every 5 seconds (default) or when the write buffer fills.
- 2.The uberblock at the top of the pool metadata tree points to the most recent valid TXG. ZFS stores a ring buffer of historical uberblocks, providing a history of recent TXGs.
- 3.
zpool import -T <txg> -o readonly=on poolnameimports the pool using a specific historical TXG instead of the most recent. This effectively rolls back the pool to an earlier consistent state. - 4.TXG rollback only works if the on-disk blocks for the older TXG have not been overwritten by subsequent writes. Copy-on-write preserves old blocks until the space is needed, so recently written pools with available free space have better rollback success rates.
- 5.Use
zdb -e -u poolnameto list available uberblocks and their TXG numbers before attempting a rollback. The-eflag lets zdb read an exported or non-imported pool directly from raw devices.
Example: If a server loses power during heavy writes, zpool import may fail because the most recent transaction group is corrupt. Running zdb -e -u poolname lists the available uberblocks and their TXG numbers, which can reveal an earlier valid uberblock. Importing with zpool import -T <txg> -o readonly=on poolname rolls the pool back to that earlier consistent state, sacrificing only the uncommitted writes from the moment of failure while preserving everything before it.
Why Does a Healthy-Looking Pool Refuse to Import?
A pool whose members are all ONLINE and whose metadata verifies can still refuse to import, because deduplication is enabled and the Deduplication Table no longer fits in the importing host's RAM. That is a ceiling on the host, not damage on the drives.
The two branches above (a corrupt latest TXG, and a vdev that has gone FAULTED or UNAVAIL) both leave visible evidence in zpool status or in SMART. This third branch leaves none.
Every member reads clean, no vdev reports errors, and zpool import never returns. When ZFS deduplication has been used on a dataset, the DDT has to be loaded into the Adaptive Replacement Cache before the import can finish, and the memory that requires is a function of how much deduplicated data the pool holds, not of how healthy the drives are.
Three outcomes, not one
A DDT that exceeds available memory does not produce a single universal result. The outcome scales with the size of the shortfall.
- 1.Modest shortfall. The DDT slightly exceeds ARC and entries start paging off disk. Because dedup requires a hash lookup for every block read or written, that turns into sustained random I/O and performance craters. The pool works; it thrashes.
- 2.Severe memory pressure.
zpool importstalls with no bound. The kernel hung-task detector logsINFO: task zpool:NNN blocked for more than 120 secondsand the pool stays unimportable on that hardware. Nothing is corrupt; the process is blocked. - 3.Full exhaustion. Memory runs out and the Linux OOM killer starts terminating userland processes, and an undersized host can panic outright. This is the outcome most write-ups describe as if it were the only one.
Separate from capacity exhaustion, there is a second family of import-time panics traced to assertion failures inside specific OpenZFS builds, where the code halts the kernel on purpose rather than proceed against metadata it considers inconsistent. Those are software defects rather than a memory ceiling, and the fix is a different build, not more RAM. The distinction matters because adding memory to a box that is panicking on an assertion buys nothing.
How to tell this branch apart from the other two
- 1.Confirm the import is hanging rather than failing. A pool with a corrupt uberblock returns an error; a DDT-starved import returns nothing at all and the command sits.
- 2.Read
dmesgon the importing host. AINFO: task zpool:NNN blocked for more than 120 secondsline from the kernel hung-task detector, with no accompanying device errors, points at memory rather than media. - 3.Establish whether deduplication was ever enabled on any dataset in the pool. The
dedupdataset property is the record. On a pool that will not import, that answer usually comes from the administrator or from the original appliance configuration, thoughzdbcan also read dataset properties straight off the member devices without importing. - 4.Compare the host's physical RAM against the deduplicated capacity. The long-standing planning figure is a rule of thumb rather than a vendor specification: the FreeNAS 8.3 manual put it as "a general rule of thumb is 5 GB RAM per TB of storage to be deduplicated." Treat it as a sizing heuristic, not a threshold the code enforces.
The read-only forensic path
Importing read-only changes the import profile. It prevents ZIL replay, and it never writes to the pool, so nothing about the attempt commits state to the drives. Adding -N suppresses automatic dataset mounting, so the host does not start touching datasets before you are ready to extract.
zpool import -o readonly=on -N <pool-name>There is no dedup off switch at import. No documented zpool import flag, property override, or kernel tunable turns deduplication off to force a failing read-write import through. Deduplication is built into the block pointer tree of the datasets that used it.
Clearing the dedup property affects only newly written blocks; every block already written stays in the DDT. Eliminating a DDT means getting rid of the deduplicated blocks themselves: import the pool, copy the data to a fresh dataset with dedup off, and destroy the original.
Because the ceiling belongs to the host, this failure is portable in the wrong direction. Drives pulled from an appliance with a large ARC and connected to a smaller workstation can take a pool that imported fine yesterday and make it unimportable today.
We image every member with ddrescue or PC-3000 Portable III hardware first, then import the images read-only on a host sized for the table. All of that work happens in-house at the Austin, TX lab, and there is no diagnostic fee for the evaluation. For the appliance-level treatment of DDT sizing and SLOG loss, see TrueNAS ZFS pool import recovery. If the import fails with device errors instead of hanging, the branch you want is ZFS pool import I/O error.
Example: If a deduplicated pool built on a host with a large amount of RAM is moved to a recovery box with a fraction of that memory, the drives read perfectly and every vdev reports ONLINE, yet the import command never completes and dmesg fills with blocked-task warnings. Adding memory to the recovery host, or importing the cloned images read-only, resolves an import that no amount of drive work would have fixed.
How Do You Handle FAULTED and UNAVAIL Vdevs?
When a vdev is FAULTED or UNAVAIL, the decision to replace or stop depends on the pool's remaining redundancy, the value of the data, and whether the failure is a drive issue or a connection issue.
- 1.Check physical connections first. UNAVAIL often means ZFS cannot find the device path. A reseated SATA cable or a different controller port may resolve it.
- 2.Check SMART data. If the drive reports reallocated sectors, pending sectors, or UNC errors, the hardware is failing.
- 3.If the pool is DEGRADED (still has margin),
zpool replace poolname old-dev new-devinitiates a resilver (ZFS term for rebuild). This reads all surviving vdev members to reconstruct the replacement. - 4.If the pool is FAULTED (no remaining margin), do not attempt to replace. The pool cannot guarantee data integrity. Image every drive and attempt offline reconstruction.
For enterprise server data recovery, FAULTED ZFS pools on production systems require imaging before any repair attempt. ZFS's copy-on-write architecture means the historical TXG data is still on-disk; any write operation (including a replace or scrub) can overwrite those blocks.
Resilver risk on unstable drives: Running zpool replace on a pool where the remaining drives have marginal heads or firmware instability forces sustained random I/O across every surviving member. Unlike a traditional RAID rebuild (which reads sequentially), ZFS resilvers follow the block pointer tree, generating random seeks that accelerate head failure on physically unstable drives. If the data is irreplaceable, image all members with ddrescue before initiating any resilver. For pools with missing top-level vdevs, the OpenZFS tunable zfs_max_missing_tvds allows importing a pool in read-only mode even when vdevs are absent, enabling data extraction without a full resilver.
Example: If a raidz1 pool is DEGRADED because one member is FAULTED with checksum errors while the surviving members report clean SMART data, replacing the failed drive initiates a resilver. Imaging every member first provides a fallback: zpool replace poolname old-dev new-dev can then be run on the live pool. If the sustained random I/O of the resilver causes a surviving drive to fail, the pool can still be reconstructed offline from the pre-resilver images.
How Do raidz1, raidz2, and raidz3 Differ in Fault Tolerance?
ZFS raidz levels map to traditional RAID data recovery parity concepts: raidz1 is single-parity (like RAID 5), raidz2 is dual-parity (like RAID 6), and raidz3 is triple-parity (no traditional RAID equivalent).
raidz1
Tolerates 1 drive failure. Same URE risk as RAID 5 during resilver. Not recommended for drives larger than 2TB.
raidz2
Tolerates 2 drive failures. The current recommendation for most ZFS deployments with large drives. Resilver can complete even with one URE.
raidz3
Tolerates 3 drive failures. Used in large-capacity deployments (12+ drives) where resilver times exceed 48 hours and multi-drive failure is a realistic scenario.
ZFS has one advantage over traditional RAID during rebuilds: it only resilvers allocated blocks, not the entire drive. A raidz2 pool at 50% capacity resilvers roughly half the data compared to a RAID 6 rebuild. This reduces both the time window and the total bytes read, lowering URE risk.
Example: When a drive fails in a partially full raidz2 pool, the resilver reads only the allocated data across the surviving members rather than the full usable capacity. Because empty unallocated space is skipped, the total bytes read during the rebuild are lower than a traditional full-disk RAID 6 rebuild, which reduces the cumulative exposure to an unrecoverable read error during the operation.
What Happens If the ZFS Encryption Key Is Lost?
If the wrapping key for an encrypted ZFS dataset is permanently lost, the data is gone and we cannot recover it. The passphrase or key file unwraps a randomly generated master key stored on disk in wrapped form; with no wrapping key, that master key stays sealed.
The counterintuitive part comes first, because it is what sends people down the wrong path. ZFS native encryption operates per dataset, not per pool and not at the block device layer. The pool imports normally with no key present. Topology reads, vdev labels verify, unencrypted datasets mount, and zpool status reports a healthy pool. The encrypted datasets sit unmounted. So "the pool imported" tells an owner nothing about whether their files are reachable.
zfs list -o name,keystatus,encryptionrootThat listing is the real status check. Each independently encrypted dataset, or a hierarchy of datasets inheriting one key configuration, carries an encryptionroot. A locked dataset shows keystatus of unavailable. Only after zfs load-key succeeds does it flip to available and allow a mount.
Where the key lives
- 1.A randomly generated master key encrypts the file data. It is created when the dataset is created and it is stored on disk in wrapped form. It never leaves the pool.
- 2.The user-supplied passphrase, raw key file, or hex key is the wrapping key, and it is held by the operator rather than by the pool.
zfs load-keyuses it to unwrap the master key into memory. - 3.With
encryption=onthe default suite isaes-256-gcm; older releases defaulted toaes-256-ccm. Passphrases derive the wrapping key through PBKDF2, and thepbkdf2itersproperty defaults to 350,000 iterations and cannot be set below 100,000. - 4.
zfs change-keyis not a way in. It re-wraps the existing master key with a new wrapping key, and it requires the dataset to already be unlocked with the current key loaded. - 5.While a dataset is unlocked, the key material resides in system memory. On a live machine that is still unlocked, dumping kernel memory to extract key material is theoretically possible. Once the machine crashes, reboots, or loses power, that material is gone and no imaging of the drives brings it back. This is not a service we offer; it is stated here so nobody powers off a still-unlocked box expecting to pick up where they left off.
Lost wrapping key means we cannot recover the data. No passphrase, no key file, no exported key configuration means the wrapped master key cannot be unwrapped. Sector-level imaging of every member drive changes nothing, because the ciphertext is intact and the problem is the missing key.
OpenZFS has no automatic key escrow and there is no hardware controller backdoor, because the key is held by the host rather than by a controller. AES-256 is not brute-forced. This is the same terminal condition as a lost Synology DSM 7.2 LUKS Encryption Key Vault: once the vault and the recovery key are both gone, extraction is mathematically impossible.
What a lab can still report
ZFS native encryption protects the data payloads and the file names, not the enclosing filesystem structure. With no key at all, an evaluation can honestly tell an owner what existed: dataset names and the filesystem hierarchy, used capacity along with quotas and reservations, snapshot names and their creation timestamps, and dataset properties such as compression algorithm, record size, cipher, and PBKDF2 iteration count.
File names and file contents inside an encrypted dataset stay obscured. That inventory is often enough to tell somebody which of several pools held the data they care about, or that the snapshot they were counting on was never taken.
On TrueNAS, which uses OpenZFS native encryption rather than anything proprietary, a key configured for automatic unlock at boot is stored in the TrueNAS configuration database on the unencrypted boot pool. Losing the boot device without a backup of that configuration or a manually exported key file loses the wrapping key, and the data pool stays sealed even though every data drive is healthy.
We run this evaluation in-house at the Austin, TX lab with no diagnostic fee, and if the key is gone we say so and charge nothing. No data, no recovery fee applies here in its most literal form. Where a key does exist and the obstacle is pool structure rather than cryptography, the work returns to imaging every member and reconstructing the pool offline from the images.
Frequently Asked Questions
Can data be recovered from a FAULTED ZFS pool?
In most cases, yes. FAULTED means ZFS has determined that the pool cannot guarantee data integrity with its current set of available vdevs. The data is still on the drives. Recovery involves imaging each drive with a write-blocker and reconstructing the pool offline. ZFS stores extensive metadata, including multiple copies of the uberblock and transaction group history, which professional tools can use to rebuild the pool state even when the live pool refuses to import.
What does UNAVAIL mean in ZFS?
UNAVAIL means ZFS cannot open the vdev at all. The drive may have failed, been disconnected, or the device path may have changed. If the vdev is part of a raidz group and too many members are UNAVAIL (more than the parity level allows), the entire pool transitions to FAULTED. A single UNAVAIL vdev in a mirror is tolerated as long as the other mirror member is ONLINE. Check 'zpool status' for the specific vdev and drive identifier.
Is it safe to use zpool clear on a degraded pool?
zpool clear resets error counters and retries I/O on vdevs that ZFS has flagged. If the errors were transient (a loose cable, a temporary controller issue), clearing can bring the vdev back online. If the errors reflect a real hardware failure, clearing masks the problem and allows the pool to continue operating with a drive that is actively failing. Future writes to that drive may be lost. Only use zpool clear if you have identified and resolved the root cause of the errors.
Why won't my ZFS pool import when every drive reports ONLINE?
If the members are all ONLINE, the metadata verifies, and zpool import hangs instead of returning an error, a common cause is deduplication. The Deduplication Table has to load into ARC before the import completes, and that memory requirement scales with how much deduplicated data the pool holds. The outcome depends on the size of the shortfall: a modest deficit pages DDT entries off disk and craters performance, severe pressure stalls the import and the kernel hung-task detector logs 'INFO: task zpool:NNN blocked for more than 120 seconds' in dmesg, and full exhaustion drives the OOM killer or a panic. The long-standing planning figure of 5 GB of RAM per 1 TB of deduplicated data is a rule of thumb from the FreeNAS 8.3 manual, not a limit the code enforces. There is no import flag or tunable that disables dedup on a pool that will not import; clearing the dedup property affects only newly written blocks. Import cloned images read-only with zpool import -o readonly=on -N on a host sized for the table.
Can a data recovery lab decrypt a ZFS dataset if the encryption key is lost?
No. We cannot, and neither can anyone else. ZFS native encryption stores a randomly generated master key on disk in wrapped form, and the passphrase, raw key file, or hex key you supply is the wrapping key that zfs load-key uses to unwrap it. With the wrapping key permanently gone, the master key stays sealed. Imaging every member drive changes nothing, because the ciphertext is intact and the missing piece is the key. OpenZFS has no key escrow and there is no controller backdoor, since the key is held by the host. Note that the pool itself still imports without a key: encryption is per dataset, so the encrypted datasets show keystatus unavailable in 'zfs list -o name,keystatus,encryptionroot'. What an evaluation can still report from a locked dataset is dataset names and hierarchy, used capacity and quotas, snapshot names with creation timestamps, and dataset properties. File names and file contents stay obscured.
Related services
Related Recovery Services
ZFS pool FAULTED or UNAVAIL?
Free evaluation. Write-blocked drive imaging. Offline pool reconstruction with TXG history preserved. No data, no fee.