hyperledger/fabric · error
block metadata is of size %d but should be of size %d
Error message
block metadata is of size %d but should be of size %d
What it means
A Fabric block's Metadata.Metadata slice must contain one entry per indexed metadata type (SIGNATURES, LAST_CONFIG, TRANSACTIONS_FILTER, ORDERER — i.e. len(cb.BlockMetadataIndex_name)). VerifyConsenterSig -> verifySignatureIsBoundToProposal checks this right after converting the proposal to a block; this error means the block derived from the proposal is missing (or has extra) metadata slots, so indexed entries like signatures or last-config cannot be located safely.
Source
Thrown at orderer/consensus/smartbft/verifier.go:422
if err := proto.Unmarshal(sig.OrdererBlockMetadata, ordererMD); err != nil {
return errors.Wrap(err, "malformed orderer metadata in signature")
}
if !bytes.Equal(ordererMD.ConsenterMetadata, prop.Metadata) {
v.Logger.Warnf("Expected consenter metadata %s but got %s in proposal",
base64.StdEncoding.EncodeToString(ordererMD.ConsenterMetadata), base64.StdEncoding.EncodeToString(prop.Metadata))
return errors.Errorf("consenter metadata in OrdererBlockMetadata doesn't match proposal")
}
block, err := ProposalToBlock(prop)
if err != nil {
v.Logger.Warnf("got malformed proposal: %v", err)
return err
}
// Ensure Metadata slice is of the right size
if len(block.Metadata.Metadata) != len(cb.BlockMetadataIndex_name) {
return errors.Errorf("block metadata is of size %d but should be of size %d",
len(block.Metadata.Metadata), len(cb.BlockMetadataIndex_name))
}
signatureMetadata := &cb.Metadata{}
if err := proto.Unmarshal(block.Metadata.Metadata[cb.BlockMetadataIndex_SIGNATURES], signatureMetadata); err != nil {
return errors.Wrap(err, "malformed signature metadata")
}
ordererMDFromBlock := &cb.OrdererBlockMetadata{}
if err := proto.Unmarshal(signatureMetadata.Value, ordererMDFromBlock); err != nil {
return errors.Wrap(err, "malformed orderer metadata in block")
}
// Ensure the block's OrdererBlockMetadata matches the signature.
if !proto.Equal(ordererMDFromBlock, ordererMD) {
return errors.Errorf("signature's OrdererBlockMetadata and OrdererBlockMetadata extracted from block do not match")
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Upgrade all ordering nodes to the same Fabric version so blocks always carry all metadata indexes.
- Ensure the channel uses the SmartBFT consenters path to build blocks (Raft/BFT plugin mismatch produces wrong metadata layout).
- Reject the proposal and force a view change so a correctly built block is proposed.
- Check any custom tooling that constructs blocks and make it populate Metadata.Metadata for every entry in cb.BlockMetadataIndex_name.
Example fix
// before: block with only 3 metadata slots
block.Metadata.Metadata = []([]byte){sigs, lastConf, txFilter} // -> error
// after: include ORDERER metadata slot (index 3)
block.Metadata.Metadata = append(block.Metadata.Metadata, ordererMDBytes) // length == len(BlockMetadataIndex_name) Defensive patterns
Strategy: validation
Validate before calling
if len(block.Metadata.GetMetadata()) != len(cb.BlockMetadataIndex_name) {
return fmt.Errorf("block has %d metadata slots, need %d",
len(block.Metadata.GetMetadata()), len(cb.BlockMetadataIndex_name))
} Try / catch
if err := verifyProposal(prop); err != nil {
if strings.Contains(err.Error(), "block metadata is of size") {
// upgrade/fix block producer, force view change
}
return err
} Prevention
- Run identical Fabric versions on all orderers (metadata slot count changed between versions)
- Ensure the channel consensus is SmartBFT end to end — no blocks built by other consensus plugins
- If building blocks in custom tooling, populate every index in cb.BlockMetadataIndex_name
When it happens
Trigger: VerifyConsenterSig -> verifySignatureIsBoundToProposal: len(block.Metadata.Metadata) != len(cb.BlockMetadataIndex_name). Happens when the proposal was built with fewer metadata entries than the current protocol expects — e.g. missing the ORDERER (index 3) entry that SmartBFT requires.
Common situations: Fabric version skew: pre-SmartBFT / older encoding with 3 metadata slots vs. 4 required; a custom block builder that doesn't populate all metadata indexes; corrupted proposal metadata; blocks produced by a non-SmartBFT consensus plugin mixed into a SmartBFT channel.
Related errors
- failed unmarshalling OrdererBlockMetadata
- expected metadata in block to be [view_id:%d latest_sequence
- last config is nil
- consenter options type mismatch
- failed to unmarshal BFT metadata configuration
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/b7044c9b95a335f8.
Report an issue: GitHub.