{"record":{"id":"9203aa553d46663b","repo":"hyperledger/fabric","slug":"failed-to-get-last-block","errorCode":null,"errorMessage":"failed to get last block","messagePattern":"failed to get last block","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/etcdraft/chain.go","lineNumber":261,"sourceCode":"\t}\n\n\tsizeLimit := opts.SnapshotIntervalSize\n\tif sizeLimit == 0 {\n\t\tsizeLimit = DefaultSnapshotIntervalSize\n\t}\n\n\t// get block number in last snapshot, if exists\n\tvar snapBlkNum uint64\n\tcc := &raftpb.ConfState{}\n\tif s := storage.Snapshot(); !raft.IsEmptySnap(s) {\n\t\tb := protoutil.UnmarshalBlockOrPanic(s.GetData())\n\t\tsnapBlkNum = b.GetHeader().GetNumber()\n\t\tcc = s.GetMetadata().GetConfState()\n\t}\n\n\tb := support.Block(support.Height() - 1)\n\tif b == nil {\n\t\treturn nil, errors.Errorf(\"failed to get last block\")\n\t}\n\n\tc := &Chain{\n\t\tconfigurator:      conf,\n\t\trpc:               rpc,\n\t\tchannelID:         support.ChannelID(),\n\t\traftID:            opts.RaftID,\n\t\tsubmitC:           make(chan *submit),\n\t\tapplyC:            make(chan apply),\n\t\thaltC:             make(chan struct{}),\n\t\tdoneC:             make(chan struct{}),\n\t\tstartC:            make(chan struct{}),\n\t\tsnapC:             make(chan *raftpb.Snapshot),\n\t\terrorC:            make(chan struct{}),\n\t\tgcC:               make(chan *gc),\n\t\tobserveC:          observeC,\n\t\tsupport:           support,\n\t\tfresh:             fresh,","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/etcdraft/chain.go#L243-L279","documentation":"NewChain fetches the last block of the channel ledger (support.Block(support.Height()-1)) to initialize chain state (block number, appended terms). If that block is nil despite the height, the ledger is inconsistent and chain startup is aborted with 'failed to get last block'. This prevents initializing raft on top of an unreadable ledger tip.","triggerScenarios":"Creating a chain where support.Height() > 0 but the last block cannot be retrieved — ledger truncation/corruption, height advanced but block data missing, or a race with ledger initialization.","commonSituations":"Orderer crash mid-block-write corrupting the ledger tip; snapshot restore leaving the ledger height inconsistent; FileLedger directory partially deleted or on a failing disk.","solutions":["Check the orderer log for prior ledger read errors and validate the channel's block files (blockindex/ledger data integrity).","Remove and re-join the channel via the participation API to rebuild the ledger from other consenters.","Restore the ledger from a healthy snapshot or copy block files from a working orderer of the same channel (with the orderer stopped).","Verify disk health and free space; replace failing storage before restarting."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"b := support.Block(support.Height() - 1)\nif b == nil {\n    return errors.New(\"ledger tip unreadable; re-sync channel before starting chain\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Guard against ledger truncation from crashes (fsync, healthy storage)","Verify snapshot restore completes before chain start","Monitor block file integrity on orderer nodes"],"tags":["orderer","etcdraft","ledger","raft"],"backgroundTag":"ledger-block-not-found","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"}