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 md

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Check len(block.Metadata.Metadata) > int(index) before calling, or handle the error per index
  2. Ensure blocks are produced by a Fabric version/consensus type that writes the requested metadata index
  3. Re-fetch the block from a healthy orderer or restore from backup
  4. 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

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


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/2dccf7e43699f420. Report an issue: GitHub.