hyperledger/fabric · error
cannot open ledger [%s], ledger status is [%s]
Error message
cannot open ledger [%s], ledger status is [%s]
What it means
After loading the ledger's metadata from the idStore, Open checks metadata.Status; if it is not msgs.Status_ACTIVE the provider refuses to open the ledger and reports the current status. Non-ACTIVE statuses (UNDER_CONSTRUCTION, UNDER_DELETION) indicate a previous create/delete operation did not finish — the peer likely crashed mid-operation — and the ledger is in a partial state that must not be used.
Source
Thrown at core/ledger/kvledger/kv_ledger_provider.go:330
if cleanupErr == nil {
return creationErr
}
return errors.WithMessage(cleanupErr, creationErr.Error())
}
// Open implements the corresponding method from interface ledger.PeerLedgerProvider
func (p *Provider) Open(ledgerID string) (ledger.PeerLedger, error) {
logger.Debugf("Open() opening kvledger: %s", ledgerID)
// Check the ID store to ensure that the chainId/ledgerId exists
ledgerMetadata, err := p.idStore.getLedgerMetadata(ledgerID)
if err != nil {
return nil, err
}
if ledgerMetadata == nil {
return nil, errors.Errorf("cannot open ledger [%s], ledger does not exist", ledgerID)
}
if ledgerMetadata.Status != msgs.Status_ACTIVE {
return nil, errors.Errorf("cannot open ledger [%s], ledger status is [%s]", ledgerID, ledgerMetadata.Status)
}
bootSnapshotMetadata, err := snapshotMetadataFromProto(ledgerMetadata.BootSnapshotMetadata)
if err != nil {
return nil, err
}
return p.open(ledgerID, bootSnapshotMetadata, false)
}
func (p *Provider) open(ledgerID string, bootSnapshotMetadata *SnapshotMetadata, initializingFromSnapshot bool) (ledger.PeerLedger, error) {
// Get the block store for a chain/ledger
blockStore, err := p.blkStoreProvider.Open(ledgerID)
if err != nil {
return nil, err
}
pvtdataStore, err := p.pvtdataStoreProvider.OpenStore(ledgerID)
if err != nil {
return nil, errView on GitHub (pinned to 2736b63f8f)
Solutions
- Restart the peer: NewProvider -> deletePartialLedgers detects UNDER_CONSTRUCTION/UNDER_DELETION ledgers at launch and deletes them, after which the channel can be re-joined cleanly.
- If the ledger should exist, re-run the channel join after the partial ledger is purged.
- If the status is UNDER_DELETION, let the deletion complete (peer launch finishes it) rather than forcing the ledger open.
- For an emergency manual repair, update the idStore metadata Status to ACTIVE only after verifying all sub-databases are consistent — otherwise prefer re-creation from a snapshot or genesis block.
Example fix
// before: forcing open a partially-created ledger fails
lgr, err := provider.Open("mychannel") // status is UNDER_CONSTRUCTION
// after: restart peer so deletePartialLedgers purges it, then re-join
// peer restart -> "A partial ledger was identified at peer launch... will be deleted"
// peer channel join -b mychannel.block
lgr, err := provider.Open("mychannel") // status is now ACTIVE Defensive patterns
Strategy: try-catch
Validate before calling
func isOpenable(metadataStatus msgs.Status) bool {
return metadataStatus == msgs.Status_ACTIVE
} Try / catch
lgr, err := provider.Open(ledgerID)
if err != nil && strings.Contains(err.Error(), "ledger status is") {
// non-ACTIVE ledger: restart peer so deletePartialLedgers purges it, then re-join
return fmt.Errorf("ledger %s is in a partial state; restart peer and re-join the channel", ledgerID)
}
if err != nil {
return err
} Prevention
- Use graceful peer shutdown (SIGTERM, not SIGKILL) so create/delete operations finish.
- Avoid restarting peers mid channel-join or mid unjoin; serialize these operations in automation.
- After abnormal shutdown, check peer logs for 'partial ledger was identified' before opening ledgers.
- Monitor ledger status after crash recovery and alert on non-ACTIVE states.
When it happens
Trigger: ledger.Provider.Open(ledgerID) where the idStore metadata for ledgerID exists but Status == msgs.Status_UNDER_CONSTRUCTION or msgs.Status_UNDER_DELETION: a peer crash/interrupt during ledger creation (channel join) or during channel unjoin left the status flag set.
Common situations: Peer killed (OOM, power loss, container restart) in the middle of joining a channel; a channel unjoin command that aborted midway; manually copied idStore from a peer that had a partially created ledger.
Related errors
- cannot open ledger [%s], ledger does not exist
- ledger already opened
- panic(err)
- config ID illegal, cannot be empty
- config ID illegal, cannot be longer than %d
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/b0db229e96190fb3.
Report an issue: GitHub.