hyperledger/fabric · error
cannot open ledger [%s], ledger does not exist
Error message
cannot open ledger [%s], ledger does not exist
What it means
OpenWithDir/Open looks up the ledger's metadata record in the idStore (LevelDB). If getLedgerMetadata returns no metadata for the given ledgerID, the provider concludes the ledger/channel was never created (or was fully deleted) on this peer and refuses to open it. This is a lookup miss, not a corruption error — the idStore simply has no entry under the metadata key for that ledger.
Source
Thrown at core/ledger/kvledger/kv_ledger_provider.go:327
ledger.Close()
}
cleanupErr := p.runCleanup(ledgerID)
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
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Verify the ledger exists: list ledgers (peer channel list) or inspect the idStore; if the channel was never joined, join it first before opening.
- If data was restored from backup, restore ALL ledger databases (idStore, state, history, pvtdata store, bookkeeping) from the same consistent snapshot.
- Confirm CORE_LEDGER_ROOTDATA / filelock path points to the same data directory the ledgers were created in.
- If the channel was intentionally deleted, stop attempting to open that ledgerID; re-join the channel if it is needed again.
Example fix
// before: opening a channel never joined on this peer
provider, _ := kvledger.NewProvider(...)
lgr, err := provider.Open("mychannel") // fails: no metadata entry
// after: join the channel first so the ledger is created
// peer channel join -b mychannel.block
lgr, err := provider.Open("mychannel") // succeeds once metadata exists in idStore Defensive patterns
Strategy: try-catch
Validate before calling
import "github.com/hyperledger/fabric/core/ledger/kvledger"
func ledgerExists(p *kvledger.Provider, ledgerID string) bool {
ids, err := p.List()
if err != nil {
return false
}
for _, id := range ids {
if id == ledgerID {
return true
}
}
return false
} Try / catch
lgr, err := provider.Open(ledgerID)
if err != nil && strings.Contains(err.Error(), "ledger does not exist") {
// channel not joined on this peer: join it or route the request elsewhere
return fmt.Errorf("ledger %s not present on this peer; join channel first", ledgerID)
}
if err != nil {
return err
} Prevention
- Check p.List() (or peer channel list) before opening a ledgerID.
- When restoring from backup, always restore idStore together with all ledger sub-databases from one snapshot.
- Keep the peer's data directory stable across restarts; don't casually change root data paths.
- Automate channel-join verification in deployment scripts before serving traffic.
When it happens
Trigger: Calling ledger.Open(ledgerID) (peer_ledger.Provider.Open) with a ledgerID that has no metadata key in the idStore: the channel was never joined on this peer, the channel was unjoined/deleted, or the idStore DB was reset/replaced while state DBs were not (or vice versa).
Common situations: Joining a channel on a peer, then restoring only part of the data (partial backup restore); pointing the peer at a fresh data directory while clients still request old channels; a channel unjoin that completed deletion; mismatched CORE_LEDGER_ROOTDATA path between peer restarts.
Related errors
- channel ID illegal, cannot be empty
- channel ID illegal, cannot be longer than %d
- failed obtaining channel state
- channel %s doesn't exist
- Channel does not exist: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/7ae1f4e78224f0f0.
Report an issue: GitHub.