What causes I/O errors during a ZFS pool import?
Pool import reads vdev labels, uberblocks, and the Meta Object Set (MOS) from every vdev member to reconstruct the pool's in-memory state. An I/O error during this process means ZFS could not read at least one required metadata block.
- 1.Physical drive failure: One or more drives in the pool have failed or are returning read errors on sectors that contain ZFS metadata. If the failed drive is part of a raidz group and the group has exhausted its parity tolerance, import fails.
- 2.Controller or cable issues: SATA/SAS cables degrade, controller ports fail, and HBA firmware can develop bugs. If kernel logs show ATA errors or device resets preceding the ZFS I/O error, the problem may be at the transport layer, not the drive.
- 3.Corrupted uberblock: ZFS stores a ring buffer of uberblocks on each vdev member. If the most recent uberblock is corrupted (from power loss during a TXG commit, for example), ZFS cannot determine the pool's last consistent state and refuses to import.
- 4.Insufficient vdev members: raidz1 tolerates one drive failure; if two or more drives are missing or faulted, the vdev becomes UNAVAIL. raidz2 tolerates two drive failures; three or more faulted drives exceeds its redundancy, and the import fails.
What diagnostic steps should you run before taking action?
Gather information about the pool and drive health before attempting any import. These commands are read-only and do not modify the pool or drives.
- 1.List available pools:
zpool import(no arguments) scans all connected drives for ZFS metadata and lists pools available for import. Note whether the pool shows as ONLINE, DEGRADED, FAULTED, or UNAVAIL. - 2.Read vdev labels:
zdb -l /dev/sdXreads the ZFS vdev label from a specific drive. This shows the pool name, pool GUID, vdev tree, and TXG number. Run on each drive to confirm all pool members are present and their labels are consistent. - 3.Check SMART data:
smartctl -a /dev/sdXfor each drive. Non-zero values in Reallocated_Sector_Ct, Current_Pending_Sector, or Offline_Uncorrectable indicate degraded media. For SSDs, check Media_Wearout_Indicator and Reallocated_NAND_Blk_Cnt. - 4.Check kernel logs: Review
dmesgorjournalctl -kfor I/O errors, SATA link resets, or device timeouts. These entries appear before the ZFS error and indicate whether the problem is at the drive level or the transport level. - 5.List uberblocks:
zdb -e -u poolnamelists the ring buffer of uberblocks and their TXG numbers. The-eflag lets zdb read an exported or non-imported pool by scanning raw devices; without it, zdb requires the pool to be imported or present in the zpool cache. If the most recent TXG is corrupt, earlier TXGs may still be valid. For pools where even-efails, fall back tozdb -l /dev/sdXto read individual device labels directly.
What are the safe ZFS pool import strategies?
If drives and cables are healthy and the issue is at the ZFS metadata level, these import strategies proceed from least invasive to most. Always attempt read-only import first.
- 1.Read-only import:
zpool import -o readonly=on poolnameimports the pool without writing metadata to the member drives; no TXGs are synced and no ZIL is replayed. Add-o cachefile=noneto prevent updatingzpool.cache. However, a read-only import still forces massive random read I/O across every member drive to traverse the ZFS metadata tree. If any drive has suspected physical failure (clicking, slow response, I/O timeouts), image all drives with a hardware write-blocker first and import the cloned images instead. If ZFS can assemble the vdev tree, copy data to a separate destination immediately. - 2.TXG rollback: If read-only import fails because the latest TXG is corrupt, try importing at an earlier transaction group:
zpool import -T <txg-number> -o readonly=on poolname. Use the TXG numbers fromzdb -lto find valid candidates. Each TXG represents roughly 5 seconds of writes at default settings. - 3.Force import (unclean shutdown only):
zpool import -f poolnametells ZFS to accept a pool that was not cleanly exported. ZFS replays the intent log (ZIL) and updates on-disk metadata. This is safe when all drives are healthy and the only issue is an unclean shutdown. If drives are failing, this writes to the drives and can overwrite recoverable metadata.
The order matters. Read-only import writes nothing to the pool's member drives. TXG rollback with readonly=on also writes nothing to the pool. Force import writes metadata updates. Each subsequent method is more invasive. If you skip straight to -f on a pool with failing drives, you may overwrite the blocks needed for recovery.
When can you resolve a ZFS pool import I/O error yourself?
Several common import failure scenarios have straightforward fixes that do not require professional recovery tools.
- 1.Device paths changed. Moving drives to a new controller, changing SATA ports, or booting a different OS changes
/dev/sd*assignments. ZFS identifies drives by GUID, not device path. Ifzpool importdoes not find the pool, tryzpool import -d /dev/disk/by-id/to scan by stable device identifiers. - 2.Unclean export after power loss. If the only issue is that the pool was not exported before shutdown,
zpool import -f poolnameis safe. ZFS replays the intent log and brings the pool to a consistent state. Confirm SMART data is clean on all drives before proceeding. - 3.Single drive failure in raidz2 or raidz3. If the I/O error is caused by one failed drive and the pool has sufficient parity margin, the pool may import in DEGRADED state. Replace the failed drive and resilver. Image all drives first if the data is irreplaceable.
- 4.Cable or controller port failure. If kernel logs show SATA link resets or device timeouts on a specific port, try a different cable or port. If the drive passes SMART tests on a different port, the original cable or port was the problem.
When should you stop and image the drives?
Stop attempting imports and image every drive if any of the following conditions apply. Further import attempts on failing hardware risk making the data unrecoverable.
- 1.Multiple drives show I/O errors or SMART degradation. If more drives are faulted than the parity level allows (for raidz1, two or more; for raidz2, three or more), the pool has exceeded its redundancy. Further import attempts stress drives that are already failing.
- 2.Read-only import and TXG rollback both fail. If ZFS cannot find a valid uberblock across any TXG, the metadata damage extends beyond what standard import tools can handle. The on-disk data may still be intact below the metadata layer, but extraction requires ZFS-aware forensic tools.
- 3.Previous repair attempts did not resolve the issue. If you have already run
zpool clear,zpool replace, orzpool scrubon the degraded pool without resolution, these operations wrote metadata updates to the drives. Image what remains before any further writes. - 4.Drives are making abnormal sounds. Clicking, grinding, or repetitive seeking sounds indicate mechanical failure. Power the drive down immediately. These drives need to be imaged with hardware that can manage weak heads and bad sectors at a level
ddrescuecannot reach.
For imaging, use ddrescue with a separate destination drive for each pool member. Work from the images for all subsequent recovery attempts. For drives with physical faults, professional NAS data recovery uses write-blocked connections and PC-3000/DeepSpar hardware to image drives that consumer tools cannot read, then reconstructs the pool offline from the images.
dRAID pools: image, then read the config string off the vdev labels
If the pool uses a dRAID vdev, the declustered-parity topology added in OpenZFS 2.1 and used on TrueNAS SCALE, the offline path is the same imaging discipline with one extra hard prerequisite. dRAID is not a friendlier RAIDZ: data, parity, and spare capacity are permuted across every member instead of sitting on fixed columns, which makes a dRAID vdev more involved to reconstruct offline than RAIDZ, not less. The whole topology is recorded in the vdev label on every member as discrete layout parameters, the same values expressed by the suffix-tagged config string used when the vdev was created:
# dRAID config string grammar: draid[parity]:[data]d:[children]c:[spares]s
draid2:4d:11c:1s
# parity = 2 redundancy level per redundancy group (1, 2, or 3)
# 4d = 4 data devices per redundancy group
# 11c = 11 total member devices in the vdev
# 1s = 1 distributed spare (sliced across all children, not a whole drive)The draid2:4d:11c:1s geometry is recorded in the vdev label on every member and is required to compute where any given block lives in the permutation layout. Read it off a surviving member with zdb -l /dev/sdX, where the vdev shows as a draid type with its parity, data, children, and spare counts as discrete fields; that geometry is the first thing to parse before applying zpool import -T <txg> -o readonly=on. A dRAID distributed spare is not a dedicated whole hot-spare drive. It is spare capacity sliced and interleaved across all children in the same permutation, so a sequential resilver writes into those distributed-spare slices rather than onto one separate disk. That fixed-width sequential rebuild reads from all children at once, which restores redundancy faster than a RAIDZ healing resilver at the cost of higher whole-array I/O load. Fault tolerance is still the parity level: a draid2 vdev survives two lost members, and losing a third before the resilver finishes faults the vdev and takes the pool offline.
We image every member through a write-blocker, read the topology string off the labels, and reconstruct on a forensic host using PC-3000 Express and Data Extractor Express RAID Edition. For enterprise TrueNAS handling of dRAID pools, see our TrueNAS server data recovery service.
Why does import fail with I/O errors when every drive is healthy?
Two ZFS-specific failure paths surface as an apparent import I/O error even when every pool member reads clean: a failed SLOG device losing in-flight synchronous writes, and a deduplication table (DDT) too large to load into RAM at import.
- 1.Failed SLOG device (ZIL loss): ZFS stages synchronous writes in the ZFS Intent Log (ZIL). When the pool has a dedicated Separate Intent Log (SLOG) device, the ZIL for sync writes lives on that SLOG until each record is committed into a transaction group (TXG) on the main pool. If the SLOG fails catastrophically following a sudden power loss, the in-flight synchronous writes staged on it cannot be replayed at import and are permanently lost. This is a stronger guarantee-break than an ordinary unclean shutdown, where the ZIL is intact and replayable. Only the unreplayed dirty sync writes are gone, not the whole pool. To import while discarding the missing log device, run
zpool import -m poolname;-maccepts the loss of those unreplayed sync writes as the cost of bringing the pool online. Confirm the log vdev is the only missing device before using it. Forcing operations on drives that also show physical read errors is destructive because ZFS writes new dirty blocks over sectors you may still need. - 2.DDT RAM exhaustion at import: Enabling ZFS deduplication builds a Deduplication Table (DDT) proportional to the pool's unique block count. The general engineering rule is roughly 5 GB of RAM per 1 TB of deduplicated data. For the pool to import, the DDT must load into the Adaptive Replacement Cache (ARC) in RAM. If the DDT exceeds available physical RAM,
zpool importhangs and can trigger a kernel panic. It surfaces to the operator as a pool that will not import, which reads like an I/O error rather than the memory-pressure problem it actually is. On that hardware the pool stays unimportable until you add RAM, import on a machine with more RAM, or temporarily disable dedup. Imaging or replacing healthy drives changes nothing. Before attempting import, size the DDT against available RAM withzpool status -D poolnameandzdb -S poolname, which prints the simulated dedup histogram and lets you estimate DDT size. ZFS dedup is never free: the RAM cost is a hard prerequisite for import, not an optimization.
Both paths misdirect drive-level troubleshooting because the member disks are fine. For TrueNAS pools built with a SLOG or dedup enabled, our layered ZFS reconstruction at the Austin, TX lab isolates the log-device and DDT variables before any write touches the members. See our TrueNAS data recovery service for how SLOG loss and DDT sizing factor into a full pool import.
Frequently Asked Questions
What does 'cannot import pool: I/O error' mean?
ZFS attempted to read metadata structures (vdev labels, uberblocks, or the Meta Object Set) from the pool's member drives and at least one read failed. The error can indicate a failed drive, a corrupted uberblock, a cable or controller issue, or too many missing vdev members for the pool's parity level. Run 'zpool import' without a pool name to see the pool's reported state, then check SMART data and kernel logs to narrow the cause.
Is 'zpool import -f' safe to run?
It depends on why the import failed. If the pool was not cleanly exported (unclean shutdown, power loss) but all drives are healthy, -f is safe. ZFS replays the intent log (ZIL) to recover synchronous writes that were acknowledged but not yet committed to a transaction group. Uncommitted asynchronous writes that existed only in RAM are lost. If drives are physically failing, -f forces ZFS to write to those drives, which can overwrite recoverable data. Check SMART data on every drive before using -f.
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 the current vdevs, but the data is still on the drives. Recovery involves imaging each drive and reconstructing the pool offline. ZFS stores redundant copies of critical metadata (uberblocks, vdev labels) that forensic tools can use even when the live pool refuses to import.
My drives are all healthy, so why won't the pool import after a power loss?
If the pool used a dedicated SLOG device that failed during the power loss, the synchronous writes staged in the ZFS Intent Log (ZIL) on that SLOG cannot be replayed at import. ZFS refuses to import because it cannot honor the sync-write guarantee, and the error looks like an I/O error even though every data drive reads clean. Only the unreplayed in-flight sync writes are lost, not the pool. Confirm the log vdev is the only missing device, then run 'zpool import -m poolname' to import while discarding the missing log. The -m flag accepts the loss of those unreplayed sync writes. Do not force this on drives that also show physical read errors, because ZFS will write new dirty blocks over sectors you may still need.
Why does my deduplicated pool hang on import?
ZFS deduplication builds a Deduplication Table (DDT) sized to the pool's unique block count, roughly 5 GB of RAM per 1 TB of deduplicated data. The DDT must load into the ARC (RAM) for the pool to import. If it exceeds physical RAM, 'zpool import' hangs and can kernel-panic, which surfaces as a pool that will not import rather than a memory error. The fix is RAM-level, not drive-level: add memory, import on a machine with more RAM, or temporarily disable dedup. Imaging or swapping healthy drives does nothing. Size the DDT against available RAM first with 'zpool status -D poolname' and 'zdb -S poolname' to estimate the table size before you attempt the import.
Can you recover a TrueNAS dRAID pool that will not import?
Yes. A dRAID vdev, the declustered-parity topology added in OpenZFS 2.1 and used on TrueNAS SCALE, is reconstructed the same forensic way as any ZFS pool: image every member through a write-blocker, then read the dRAID config string off the vdev labels. The grammar is suffix-tagged, draid[parity]:[data]d:[children]c:[spares]s, for example draid2:4d:11c:1s (parity level 2, 4 data devices per redundancy group, 11 total children, 1 distributed spare). Those layout parameters, the parity, data-per-group, children, and spare counts that the string encodes, are recorded in the vdev label on every member and are read back with 'zdb -l'; they are required to compute where any given block lives in the permutation layout, so they are the first thing to parse before applying 'zpool import -T <txg> -o readonly=on'. A dRAID distributed spare is not a whole hot-spare drive; it is spare capacity sliced across all children, so a sequential resilver writes into those slices rather than onto one separate disk. The declustered layout is more involved to reconstruct offline than RAIDZ, not less, and fault tolerance is still the parity level.
Related services
Related Recovery Services
Synology, QNAP, TrueNAS, and other NAS
Full RAID recovery service overview
Enterprise server recovery
FAULTED and UNAVAIL pool recovery
Synology NAS volume recovery
QuTS hero ZFS pool reconstruction
Transparent cost breakdown
ZFS pool import failing with I/O errors?
Free evaluation. Write-blocked drive imaging. Offline pool reconstruction with TXG history preserved. No data, no fee.