hyperledger/fabric · error
snapshot dir %s is empty
Error message
snapshot dir %s is empty
What it means
CreateLedgerFromSnapshot validates that the supplied snapshotDir exists and is non-empty before starting the join-by-snapshot bootstrap. fileutil.DirEmpty reports the directory has no content, meaning the snapshot metadata/files were never generated, were deleted, or the wrong path was given. The operation is aborted before any state is changed.
Source
Thrown at core/ledger/ledgermgmt/ledger_mgmt.go:141
return &closableLedger{
ledgerMgr: m,
id: id,
PeerLedger: l,
}, nil
}
// CreateLedgerFromSnapshot creates a new ledger with the given snapshot and executes the callback function
// after the ledger is created. This function launches to goroutine to create the ledger and call the callback func.
// All ledger dbs would be created in an atomic action. The channel id retrieved from the snapshot metadata
// is treated as a ledger id. It returns an error if another ledger is being created from a snapshot.
func (m *LedgerMgr) CreateLedgerFromSnapshot(snapshotDir string, channelCallback func(ledger.PeerLedger, string)) error {
// verify snapshotDir exists and is not empty
empty, err := fileutil.DirEmpty(snapshotDir)
if err != nil {
return err
}
if empty {
return errors.Errorf("snapshot dir %s is empty", snapshotDir)
}
if err := m.setJoinBySnapshotStatus(snapshotDir); err != nil {
return err
}
go func() {
defer m.resetJoinBySnapshotStatus()
ledger, cid, err := m.createFromSnapshot(snapshotDir)
if err != nil {
logger.Errorw("Error creating ledger from snapshot", "snapshotDir", snapshotDir, "error", err)
return
}
channelCallback(ledger, cid)
}()
View on GitHub (pinned to 2736b63f8f)
Solutions
- Point the operation at a concrete snapshot directory (rootDir/generatedSnapshots/<snapshotName>) that contains snapshot files, not the snapshots root.
- Verify the snapshot files were copied intact to this peer; re-transfer if missing.
- If no valid snapshot exists, generate a new one on a source peer (GenerateSnapshot) and retry.
Example fix
// before
mgr.CreateLedgerFromSnapshot("/var/hyperledger/production/snapshots")
// after
mgr.CreateLedgerFromSnapshot("/var/hyperledger/production/snapshots/completedSnapshots/snapshot-123") Defensive patterns
Strategy: validation
Validate before calling
entries, err := os.ReadDir(snapshotDir)
if err != nil || len(entries) == 0 {
return fmt.Errorf("snapshot dir %s missing or empty", snapshotDir)
} Try / catch
if err := mgr.CreateLedgerFromSnapshot(dir); err != nil {
if strings.Contains(err.Error(), "is empty") {
// fall back to genesis-block join or re-copy snapshot
}
return err
} Prevention
- Pass the exact snapshot directory (rootDir/generatedSnapshots/<name>), never the snapshots root.
- Verify file counts/checksums after transferring snapshots between peers.
- Confirm snapshot generation completed successfully before initiating the join.
When it happens
Trigger: Calling LedgerMgr.CreateLedgerFromSnapshot(snapshotDir) where snapshotDir exists but contains no files (e.g. snapshot generation never completed, files moved, or the root of the snapshots directory was passed instead of a specific snapshot's directory).
Common situations: Configuring peer.core.yaml's ledger.snapshots.rootDir and pointing joinBySnapshot at the root instead of an actual snapshot directory; a snapshot whose files were lost during transfer to the joining peer; a crashed/partial snapshot generation.
Related errors
- error opening block file %s
- error seeking block file [%s] to startOffset [%d]
- error getting block file stat
- error reading dir %s
- config history for ledger [%s] exists. Incremental import is
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/34be2441667a627b.
Report an issue: GitHub.