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

  1. Point the operation at a concrete snapshot directory (rootDir/generatedSnapshots/<snapshotName>) that contains snapshot files, not the snapshots root.
  2. Verify the snapshot files were copied intact to this peer; re-transfer if missing.
  3. 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

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


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/34be2441667a627b. Report an issue: GitHub.