{"record":{"id":"ea9ddd7a22eb156c","repo":"hyperledger/fabric","slug":"a-ledger-is-being-created-from-a-snapshot-at-s-c","errorCode":null,"errorMessage":"a ledger is being created from a snapshot at %s. Call ledger creation again after it is done.","messagePattern":"a ledger is being created from a snapshot at (.+?)\\. Call ledger creation again after it is done\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/ledger/ledgermgmt/ledger_mgmt.go","lineNumber":111,"sourceCode":"\t// TODO remove the following package level init\n\tcceventmgmt.Initialize(&chaincodeInfoProviderImpl{\n\t\tledgerMgr,\n\t\tinitializer.DeployedChaincodeInfoProvider,\n\t})\n\tlogger.Info(\"Initialized LedgerMgr\")\n\treturn ledgerMgr\n}\n\n// CreateLedger creates a new ledger with the given genesis block.\n// This function guarantees that the creation of ledger and committing the genesis block would an atomic action.\n// The channel id retrieved from the genesis block is treated as a ledger id.\n// It returns an error if another ledger is being created from a snapshot.\nfunc (m *LedgerMgr) CreateLedger(id string, genesisBlock *common.Block) (ledger.PeerLedger, error) {\n\tm.creationLock.Lock()\n\tdefer m.creationLock.Unlock()\n\n\tif m.joinBySnapshotStatus.InProgress {\n\t\treturn nil, errors.Errorf(\"a ledger is being created from a snapshot at %s. Call ledger creation again after it is done.\", m.joinBySnapshotStatus.BootstrappingSnapshotDir)\n\t}\n\n\tm.lock.Lock()\n\tdefer m.lock.Unlock()\n\tlogger.Infof(\"Creating ledger [%s] with genesis block\", id)\n\tl, err := m.ledgerProvider.CreateFromGenesisBlock(genesisBlock)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tm.openedLedgers[id] = l\n\tlogger.Infof(\"Created ledger [%s] with genesis block\", id)\n\treturn &closableLedger{\n\t\tledgerMgr:  m,\n\t\tid:         id,\n\t\tPeerLedger: l,\n\t}, nil\n}\n","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/ledger/ledgermgmt/ledger_mgmt.go#L93-L129","documentation":"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.","triggerScenarios":"Calling LedgerMgr.CreateLedger (directly or via createOrOpenChains, CreateMockChannel, CreateChannel) while a CreateLedgerFromSnapshot for another channel is still running (m.joinBySnapshotStatus.InProgress == true).","commonSituations":"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.","solutions":["Retry CreateLedger after the in-progress snapshot join finishes (the message says to call again).","Serialize channel-join operations so CreateLedger is not invoked concurrently with CreateLedgerFromSnapshot.","Wait for the snapshot join to complete (or trigger its completion/restart the node if it is stuck) before creating ledgers."],"exampleFix":"// before (concurrent join attempts)\ngo mgr.CreateLedger(\"channel2\", genesisBlock)\n// after (wait for snapshot join, then retry)\nfor mgr.JoinBySnapshotInProgress() {\n    time.Sleep(500 * time.Millisecond)\n}\nl, err := mgr.CreateLedger(\"channel2\", genesisBlock)","handlingStrategy":"retry","validationCode":"if mgr.JoinBySnapshotInProgress() {\n    return errors.New(\"defer ledger creation until snapshot join completes\")\n}","typeGuard":null,"tryCatchPattern":"for attempts := 0; attempts < 5; attempts++ {\n    lgr, err := mgr.CreateLedger(id, genesisBlock)\n    if err == nil { break }\n    if strings.Contains(err.Error(), \"ledger is being created from a snapshot\") {\n        time.Sleep(2 * time.Second); continue\n    }\n    return err\n}","preventionTips":["Serialize all channel-join/ledger-creation calls behind one mutex or task queue.","Never call CreateLedger concurrently with CreateLedgerFromSnapshot.","Track snapshot-join completion events before issuing further ledger operations."],"tags":["ledger","concurrency","fabric"],"backgroundTag":"operation-in-progress-conflict","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}