hyperledger/fabric · error
unable to retrieve last config block [%d]
Error message
unable to retrieve last config block [%d]
What it means
LastConfigBlock reads the last-config index from a config block and then asks the BlockRetriever (cluster service's block store abstraction) for that block number. If the retriever returns nil — the block is not available locally yet — this error reports the missing index.
Source
Thrown at orderer/common/cluster/util.go:526
// or nil if such a block doesn't exist.
Block(number uint64) *common.Block
}
// LastConfigBlock returns the last config block relative to the given block.
func LastConfigBlock(block *common.Block, blockRetriever BlockRetriever) (*common.Block, error) {
if block == nil {
return nil, errors.New("nil block")
}
if blockRetriever == nil {
return nil, errors.New("nil blockRetriever")
}
lastConfigBlockNum, err := protoutil.GetLastConfigIndexFromBlock(block)
if err != nil {
return nil, err
}
lastConfigBlock := blockRetriever.Block(lastConfigBlockNum)
if lastConfigBlock == nil {
return nil, errors.Errorf("unable to retrieve last config block [%d]", lastConfigBlockNum)
}
return lastConfigBlock, nil
}
// StreamCountReporter reports the number of streams currently connected to this node
type StreamCountReporter struct {
Metrics *Metrics
count uint32
}
func (scr *StreamCountReporter) Increment() {
count := atomic.AddUint32(&scr.count, 1)
scr.Metrics.reportStreamCount(count)
}
func (scr *StreamCountReporter) Decrement() {
count := atomic.AddUint32(&scr.count, ^uint32(0))
scr.Metrics.reportStreamCount(count)View on GitHub (pinned to 2736b63f8f)
Solutions
- Allow the block puller to catch up, or pull the missing block from another orderer before retrying.
- Check the retriever's block availability (ledger height vs. lastConfigBlockNum) and storage health.
- Restart the ordering node so onboarding/replay of the channel ledger occurs.
- Restore from a snapshot or rejoin the channel if ledger data was permanently lost.
Defensive patterns
Strategy: retry
Validate before calling
// Check local availability before requesting the last config block
if retriever.Height() <= lastConfigBlockNum {
return errors.New("last config block not yet available locally")
} Try / catch
blk, err := cluster.LastConfigBlock(block, retriever)
if err != nil {
if strings.Contains(err.Error(), "unable to retrieve last config block") {
time.Sleep(pullRetryInterval)
return retryLastConfigBlock(block, retriever)
}
return err
} Prevention
- Let newly joined orderers finish onboarding/catch-up before serving verification requests.
- Monitor ledger height across the ordering cluster.
- Never manually delete or trim orderer ledger files.
When it happens
Trigger: Calling LastConfigBlock when blockRetriever.Block(lastConfigBlockNum) returns nil, e.g. the orderer has not yet pulled/retained the referenced last-config block, or the ledger was pruned below that height.
Common situations: A freshly started or catching-up orderer whose local ledger lacks older config blocks, BFT-puller bootstrapping before the needed block arrives, ledger files corrupted or manually trimmed.
Related errors
- ErrChannelRemovalFailure
- cannot enable channel capabilities without orderer support f
- Must set some OrdererAddresses
- unexpected end of blockfile
- error opening block file %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/60b3c6639fc0d555.
Report an issue: GitHub.