hyperledger/fabric · error
err
Error message
err
What it means
GetLastConfigIndexFromBlockOrPanic is a convenience wrapper that calls GetLastConfigIndexFromBlock and panics on any error. The bare message "err" is simply the underlying error (unmarshalling failure or missing metadata) propagated as a panic. It indicates the block's last-config metadata could not be parsed or is absent.
Source
Thrown at protoutil/blockutils.go:215
return 0, errors.Wrap(err, "error unmarshalling LastConfig")
}
return lc.Index, nil
}
obm := &cb.OrdererBlockMetadata{}
err = proto.Unmarshal(m.Value, obm)
if err != nil {
return 0, errors.Wrap(err, "failed to unmarshal orderer block metadata")
}
return obm.LastConfig.Index, nil
}
// GetLastConfigIndexFromBlockOrPanic retrieves the index of the last config
// block as encoded in the block metadata, or panics on error
func GetLastConfigIndexFromBlockOrPanic(block *cb.Block) uint64 {
index, err := GetLastConfigIndexFromBlock(block)
if err != nil {
panic(err)
}
return index
}
// CopyBlockMetadata copies metadata from one block into another
func CopyBlockMetadata(src *cb.Block, dst *cb.Block) {
dst.Metadata = src.Metadata
// Once copied initialize with rest of the
// required metadata positions.
InitBlockMetadata(dst)
}
// InitBlockMetadata initializes metadata structure
func InitBlockMetadata(block *cb.Block) {
if block.Metadata == nil {
block.Metadata = &cb.BlockMetadata{Metadata: [][]byte{{}, {}, {}, {}, {}}}
} else if len(block.Metadata.Metadata) < int(cb.BlockMetadataIndex_COMMIT_HASH+1) {
for i := len(block.Metadata.Metadata); i <= int(cb.BlockMetadataIndex_COMMIT_HASH); i++ {View on GitHub (pinned to 2736b63f8f)
Solutions
- Fix the caller to pass a real, valid block (with populated Metadata entries)
- Switch to the non-panicking GetLastConfigIndexFromBlock and handle the error explicitly in production paths
- Validate block.Metadata length (>= LAST_CONFIG index+1) before calling
- Re-fetch the block from the ledger if its data is corrupt
Example fix
// before
index, err := GetLastConfigIndexFromBlock(block)
if err != nil {
panic(err)
}
// after (caller side)
index, err := GetLastConfigIndexFromBlock(block)
if err != nil {
return fmt.Errorf("block %d has no readable last-config metadata: %w", block.GetHeader().GetNumber(), err)
} Defensive patterns
Strategy: type-guard
Validate before calling
func safeLastConfigIndex(block *cb.Block) (uint64, error) {
if block == nil || block.GetMetadata() == nil {
return 0, errors.New("block has no metadata")
}
return GetLastConfigIndexFromBlock(block)
} Type guard
func hasReadableLastConfig(block *cb.Block) bool {
_, err := GetLastConfigIndexFromBlock(block)
return err == nil
} Try / catch
defer func() {
if r := recover(); r != nil {
logger.Errorf("GetLastConfigIndexFromBlockOrPanic failed: %v", r)
}
}() Prevention
- Avoid the OrPanic wrapper outside of tests; prefer GetLastConfigIndexFromBlock
- Validate block.Metadata is populated before calling
- Only call on blocks known to come from the ordering service
- Wrap calls in recover() when panicking paths are unavoidable
When it happens
Trigger: Calling GetLastConfigIndexFromBlockOrPanic with a block whose ORDERER/LAST_CONFIG metadata is missing, empty, or fails to unmarshal as LastConfig/OrdererBlockMetadata — e.g. a non-orderer block or corrupt data.
Common situations: Test code or chaincode/orderer paths passing a synthesized block without metadata, passing a block from a wrong channel type, or corrupt ledger data reaching a code path that assumes validity.
Related errors
- last config is nil
- error unmarshalling LastConfig
- panic(err)
- Could not seek block file [%s] to startOffset [%d]. New posi
- Error in decoding varint bytes [%#v]
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/258bef6c0b85494d.
Report an issue: GitHub.