{"record":{"id":"b62bc21efb7598cb","repo":"hyperledger/fabric","slug":"could-not-retrieve-header-of-the-last-block-form-f","errorCode":null,"errorMessage":"Could not retrieve header of the last block form file: %s","messagePattern":"Could not retrieve header of the last block form file: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"common/ledger/blkstorage/blockfile_mgr.go","lineNumber":161,"sourceCode":"\n\tif err := mgr.syncIndex(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tbcInfo := &common.BlockchainInfo{}\n\n\tif mgr.bootstrappingSnapshotInfo != nil {\n\t\tbcInfo.Height = mgr.bootstrappingSnapshotInfo.LastBlockNum + 1\n\t\tbcInfo.CurrentBlockHash = mgr.bootstrappingSnapshotInfo.LastBlockHash\n\t\tbcInfo.PreviousBlockHash = mgr.bootstrappingSnapshotInfo.PreviousBlockHash\n\t\tbcInfo.BootstrappingSnapshotInfo = &common.BootstrappingSnapshotInfo{}\n\t\tbcInfo.BootstrappingSnapshotInfo.LastBlockInSnapshot = mgr.bootstrappingSnapshotInfo.LastBlockNum\n\t}\n\n\tif !blockfilesInfo.noBlockFiles {\n\t\tlastBlockHeader, err := mgr.retrieveBlockHeaderByNumber(blockfilesInfo.lastPersistedBlock)\n\t\tif err != nil {\n\t\t\tpanic(fmt.Sprintf(\"Could not retrieve header of the last block form file: %s\", err))\n\t\t}\n\t\t// update bcInfo with lastPersistedBlock\n\t\tbcInfo.Height = blockfilesInfo.lastPersistedBlock + 1\n\t\tbcInfo.CurrentBlockHash = protoutil.BlockHeaderHash(lastBlockHeader)\n\t\tbcInfo.PreviousBlockHash = lastBlockHeader.PreviousHash\n\t}\n\tmgr.bcInfo.Store(bcInfo)\n\treturn mgr, nil\n}\n\nfunc bootstrapFromSnapshottedTxIDs(\n\tledgerID string,\n\tsnapshotDir string,\n\tsnapshotInfo *SnapshotInfo,\n\tconf *Conf,\n\tindexStore *leveldbhelper.DBHandle,\n) error {\n\trootDir := conf.getLedgerBlockDir(ledgerID)","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/ledger/blkstorage/blockfile_mgr.go#L143-L179","documentation":"During blockfileMgr startup, after scanning block files, the manager retrieves the header of the last persisted block to seed the blockchain info. If that retrieval fails (corrupt or truncated final block file segment), it panics because the ledger height/hash cannot be determined reliably.","triggerScenarios":"newBlockfileMgr with existing non-empty block files where retrieveBlockHeaderByNumber(lastPersistedBlock) fails — typically the last block in the newest blockfile is truncated/incomplete due to a crash mid-write, or the file is unreadable.","commonSituations":"Peer killed mid-commit leaving a partial block record; disk corruption; block files copied/rsynced while peer was running; manual truncation of blockfile_*.log segments.","solutions":["Restore block files from backup taken while the peer was stopped","Remove the incomplete trailing data from the newest blockfile segment (truncate to the last complete block boundary) or remove the corrupt segment and re-sync the ledger from ordering service/peer gossip","Check file permissions and disk health (fsck) on the ledger data directory","As a last resort, reset the ledger and re-fetch blocks from the network"],"exampleFix":"// before: panic 'Could not retrieve header of the last block form file'\n// after: restore consistent block files\nsystemctl stop peer\n# restore blockfile_000000 files from a known-good backup\nrm -rf /var/hyperledger/production/ledgersData/chains/chains/mychannel/index\nsystemctl start peer  # index rebuilt from consistent files","handlingStrategy":"try-catch","validationCode":"// verify the newest blockfile ends on a complete block before opening\nfunc lastFileLooksComplete(rootDir string) error {\n\tfiles, _ := filepath.Glob(filepath.Join(rootDir, \"blockfile_*.log\"))\n\tif len(files) == 0 { return nil }\n\tinfo, err := os.Stat(files[len(files)-1])\n\tif err != nil { return err }\n\tif info.Size() == 0 { return errors.New(\"last blockfile is empty/truncated\") }\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        if strings.Contains(fmt.Sprint(r), \"Could not retrieve header of the last block\") {\n            log.Errorf(\"last block unreadable/corrupt: %v; restore block files from backup\", r)\n        }\n    }\n}()","preventionTips":["Always stop the peer before copying/backing up ledger data","Use crash-consistent storage or take backups only while the peer is down","Monitor for unclean shutdowns and verify block files after crashes","Keep offsite backups of ledgersData for recovery"],"tags":["hyperledger-fabric","ledger","blockfile","corruption","panic"],"backgroundTag":"ledger-block-file-corruption","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"}