hyperledger/fabric · error

a ledger is being created from a snapshot at %s. Call ledger

Error message

a ledger is being created from a snapshot at %s. Call ledger creation again after it is done.

What it means

CreateLedger refuses to create a new ledger while another ledger is concurrently being bootstrapped from a snapshot. The ledger manager serializes ledger creation; a snapshot-based join sets an in-progress flag protected by creationLock, and any interleaved CreateLedger call is rejected with the directory of the snapshot being processed. The caller is expected to retry the ledger creation after the snapshot join completes.

Source

Thrown at core/ledger/ledgermgmt/ledger_mgmt.go:111

	// TODO remove the following package level init
	cceventmgmt.Initialize(&chaincodeInfoProviderImpl{
		ledgerMgr,
		initializer.DeployedChaincodeInfoProvider,
	})
	logger.Info("Initialized LedgerMgr")
	return ledgerMgr
}

// CreateLedger creates a new ledger with the given genesis block.
// This function guarantees that the creation of ledger and committing the genesis block would an atomic action.
// The channel id retrieved from the genesis block is treated as a ledger id.
// It returns an error if another ledger is being created from a snapshot.
func (m *LedgerMgr) CreateLedger(id string, genesisBlock *common.Block) (ledger.PeerLedger, error) {
	m.creationLock.Lock()
	defer m.creationLock.Unlock()

	if m.joinBySnapshotStatus.InProgress {
		return nil, errors.Errorf("a ledger is being created from a snapshot at %s. Call ledger creation again after it is done.", m.joinBySnapshotStatus.BootstrappingSnapshotDir)
	}

	m.lock.Lock()
	defer m.lock.Unlock()
	logger.Infof("Creating ledger [%s] with genesis block", id)
	l, err := m.ledgerProvider.CreateFromGenesisBlock(genesisBlock)
	if err != nil {
		return nil, err
	}
	m.openedLedgers[id] = l
	logger.Infof("Created ledger [%s] with genesis block", id)
	return &closableLedger{
		ledgerMgr:  m,
		id:         id,
		PeerLedger: l,
	}, nil
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Retry CreateLedger after the in-progress snapshot join finishes (the message says to call again).
  2. Serialize channel-join operations so CreateLedger is not invoked concurrently with CreateLedgerFromSnapshot.
  3. Wait for the snapshot join to complete (or trigger its completion/restart the node if it is stuck) before creating ledgers.

Example fix

// before (concurrent join attempts)
go mgr.CreateLedger("channel2", genesisBlock)
// after (wait for snapshot join, then retry)
for mgr.JoinBySnapshotInProgress() {
    time.Sleep(500 * time.Millisecond)
}
l, err := mgr.CreateLedger("channel2", genesisBlock)
Defensive patterns

Strategy: retry

Validate before calling

if mgr.JoinBySnapshotInProgress() {
    return errors.New("defer ledger creation until snapshot join completes")
}

Try / catch

for attempts := 0; attempts < 5; attempts++ {
    lgr, err := mgr.CreateLedger(id, genesisBlock)
    if err == nil { break }
    if strings.Contains(err.Error(), "ledger is being created from a snapshot") {
        time.Sleep(2 * time.Second); continue
    }
    return err
}

Prevention

When it happens

Trigger: Calling LedgerMgr.CreateLedger (directly or via createOrOpenChains, CreateMockChannel, CreateChannel) while a CreateLedgerFromSnapshot for another channel is still running (m.joinBySnapshotStatus.InProgress == true).

Common situations: Joining multiple channels at startup where one joins by snapshot and others by genesis block; a channel-creation request arriving mid-snapshot-restore; concurrent service initialization racing on ledger creation.

Related errors


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