{"record":{"id":"0ef6988061b413b6","repo":"hyperledger/fabric","slug":"ledger-is-empty","errorCode":null,"errorMessage":"ledger is empty","messagePattern":"ledger is empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"orderer/common/follower/follower_chain.go","lineNumber":582,"sourceCode":"\t\t\t\t}\n\t\t\t\tif updateEndpoints {\n\t\t\t\t\tendpoints, err := cluster.EndpointconfigFromConfigBlock(nextBlock, c.cryptoProvider)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn n, errors.WithMessagef(err, \"failed to extract endpoints from last config,  block number: %d\", nextBlock.Header.Number)\n\t\t\t\t\t}\n\t\t\t\t\tc.blockPuller.UpdateEndpoints(endpoints)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tc.logger.Debugf(\"Pulled blocks from %d to %d\", firstBlockToPull, targetHeight)\n\treturn targetHeight - firstBlockToPull, nil\n}\n\nfunc (c *Chain) loadLastConfig() error {\n\theight := c.ledgerResources.Height()\n\tif height == 0 {\n\t\treturn errors.New(\"ledger is empty\")\n\t}\n\tlastBlock := c.ledgerResources.Block(height - 1)\n\tindex, err := protoutil.GetLastConfigIndexFromBlock(lastBlock)\n\tif err != nil {\n\t\treturn errors.WithMessage(err, \"chain does have appropriately encoded last config in its latest block\")\n\t}\n\tlastConfig := c.ledgerResources.Block(index)\n\tif lastConfig == nil {\n\t\treturn errors.Errorf(\"could not retrieve config block from index %d\", index)\n\t}\n\tc.lastConfig = lastConfig\n\treturn nil\n}\n","sourceCodeStart":564,"sourceCodeEnd":596,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/follower/follower_chain.go#L564-L596","documentation":"Chain.loadLastConfig reads the follower's ledger to locate the last configuration block, but Height() returned 0 — the ledger contains no blocks at all. The code fails fast because a follower chain cannot operate without at least the join/genesis block present.","triggerScenarios":"loadLastConfig is called from NewChain or pullAfterJoin when c.ledgerResources.Height() == 0, i.e. the ledger was created but never populated with the join block, or all blocks were removed before the chain started.","commonSituations":"Orderer joined a channel via the Join REST API but the join block failed to be committed; ledger directory wiped or recreated by admin/automation while state files persisted; a fresh container where the genesis/join block generation step failed.","solutions":["Re-join the channel so the join block is appended: POST to the channel Join API with a valid config block, or recreate the ledger genesis.","Check the orderer logs for a prior failure committing the join block, and ensure the ledger path is writable and not mounted empty.","If the ledger was intentionally reset, follow the documented reset/rollback procedure (orderer reset) so the genesis block is restored.","Validate the onboarding pipeline (joinBlock retrieval) — a nil/failed joinBlock leaves height at 0."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if ledgerResources.Height() == 0 { return errors.New(\"refusing to start follower: ledger has no blocks; join the channel first\") }","typeGuard":null,"tryCatchPattern":"if err := NewChain(...); err != nil && err.Error() == \"ledger is empty\" { re-join channel to append join block, then retry }","preventionTips":["Ensure the channel Join API succeeded (check response + logs) before starting chain components","Keep the join block artifact and re-apply it after any ledger reset","Use the documented orderer reset/rollback procedures instead of manual file deletion"],"tags":["orderer","fabric","ledger-empty","follower"],"backgroundTag":"empty-ledger","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"}