hyperledger/fabric · error
no metadata at index [%s]
Error message
no metadata at index [%s]
What it means
GetMetadataFromBlock returns this error when the block has a Metadata section but its Metadata slice is shorter than the requested index, meaning the requested metadata entry (e.g. SIGNATURES, LAST_CONFIG, ORDERER) was never written into the block. It indicates a structurally incomplete block.
Source
Thrown at protoutil/blockutils.go:131
if payload.Header == nil {
return "", errors.New("failed to retrieve channel id - payload header is empty")
}
chdr, err := UnmarshalChannelHeader(payload.GetHeader().GetChannelHeader())
if err != nil {
return "", err
}
return chdr.ChannelId, nil
}
// GetMetadataFromBlock retrieves metadata at the specified index.
func GetMetadataFromBlock(block *cb.Block, index cb.BlockMetadataIndex) (*cb.Metadata, error) {
if block.Metadata == nil {
return nil, errors.New("no metadata in block")
}
if len(block.Metadata.Metadata) <= int(index) {
return nil, errors.Errorf("no metadata at index [%s]", index)
}
md := &cb.Metadata{}
err := proto.Unmarshal(block.Metadata.Metadata[index], md)
if err != nil {
return nil, errors.Wrapf(err, "error unmarshalling metadata at index [%s]", index)
}
return md, nil
}
// GetMetadataFromBlockOrPanic retrieves metadata at the specified index, or
// panics on error
func GetMetadataFromBlockOrPanic(block *cb.Block, index cb.BlockMetadataIndex) *cb.Metadata {
md, err := GetMetadataFromBlock(block, index)
if err != nil {
panic(err)
}
return mdView on GitHub (pinned to 2736b63f8f)
Solutions
- Check len(block.Metadata.Metadata) > int(index) before calling, or handle the error per index
- Ensure blocks are produced by a Fabric version/consensus type that writes the requested metadata index
- Re-fetch the block from a healthy orderer or restore from backup
- Update test fixtures to populate all required metadata indices
Example fix
// before
md, err := protoutil.GetMetadataFromBlock(blk, cb.BlockMetadataIndex_ORDERER)
// after
if blk.Metadata != nil && len(blk.Metadata.Metadata) <= int(cb.BlockMetadataIndex_ORDERER) {
return errors.New("block lacks ORDERER metadata")
}
md, err := protoutil.GetMetadataFromBlock(blk, cb.BlockMetadataIndex_ORDERER) Defensive patterns
Strategy: validation
Validate before calling
if blk == nil || blk.Metadata == nil || len(blk.Metadata.Metadata) <= int(cb.BlockMetadataIndex_ORDERER) {
return errors.New("block missing required metadata index")
}
md, err := protoutil.GetMetadataFromBlock(blk, cb.BlockMetadataIndex_ORDERER) Type guard
func hasMetadataIndex(b *cb.Block, idx cb.BlockMetadataIndex) bool {
return b != nil && b.Metadata != nil && len(b.Metadata.Metadata) > int(idx)
} Try / catch
md, err := protoutil.GetMetadataFromBlock(blk, idx)
if err != nil {
var missing bool
if strings.HasPrefix(err.Error(), "no metadata at index") { missing = true }
if missing {
log.Warnf("block %d missing metadata index %v", blk.Header.Number, idx)
return errSkipIndex
}
return err
} Prevention
- Ensure the consensus plugin writes every required BlockMetadataIndex before committing
- Keep ordering nodes on Fabric versions that emit the indices you read
- Populate all metadata indices in test fixtures
- Bounds-check the metadata slice for any index you intend to read
When it happens
Trigger: GetMetadataFromBlock(block, index) called with index >= len(block.Metadata.Metadata) — e.g. asking for BlockMetadataIndex_ORDERER on a block that only has SIGNATURES and LAST_CONFIG entries.
Common situations: Blocks produced by older versions or other consensus plugins lacking the ORDERER metadata entry; hand-built test blocks; corrupted/partial writes to the block store.
Related errors
- no metadata in block
- failed to retrieve channel id - block is empty
- error unmarshalling metadata at index [%s]
- identity index out of range, requested %v, but identities le
- BlockDataHashStructure width only supported at MaxUint32 in
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/2dccf7e43699f420.
Report an issue: GitHub.