{"record":{"id":"b7044c9b95a335f8","repo":"hyperledger/fabric","slug":"block-metadata-is-of-size-d-but-should-be-of-size","errorCode":null,"errorMessage":"block metadata is of size %d but should be of size %d","messagePattern":"block metadata is of size (.+?) but should be of size (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/verifier.go","lineNumber":422,"sourceCode":"\tif err := proto.Unmarshal(sig.OrdererBlockMetadata, ordererMD); err != nil {\n\t\treturn errors.Wrap(err, \"malformed orderer metadata in signature\")\n\t}\n\n\tif !bytes.Equal(ordererMD.ConsenterMetadata, prop.Metadata) {\n\t\tv.Logger.Warnf(\"Expected consenter metadata %s but got %s in proposal\",\n\t\t\tbase64.StdEncoding.EncodeToString(ordererMD.ConsenterMetadata), base64.StdEncoding.EncodeToString(prop.Metadata))\n\t\treturn errors.Errorf(\"consenter metadata in OrdererBlockMetadata doesn't match proposal\")\n\t}\n\n\tblock, err := ProposalToBlock(prop)\n\tif err != nil {\n\t\tv.Logger.Warnf(\"got malformed proposal: %v\", err)\n\t\treturn err\n\t}\n\n\t// Ensure Metadata slice is of the right size\n\tif len(block.Metadata.Metadata) != len(cb.BlockMetadataIndex_name) {\n\t\treturn errors.Errorf(\"block metadata is of size %d but should be of size %d\",\n\t\t\tlen(block.Metadata.Metadata), len(cb.BlockMetadataIndex_name))\n\t}\n\n\tsignatureMetadata := &cb.Metadata{}\n\tif err := proto.Unmarshal(block.Metadata.Metadata[cb.BlockMetadataIndex_SIGNATURES], signatureMetadata); err != nil {\n\t\treturn errors.Wrap(err, \"malformed signature metadata\")\n\t}\n\n\tordererMDFromBlock := &cb.OrdererBlockMetadata{}\n\tif err := proto.Unmarshal(signatureMetadata.Value, ordererMDFromBlock); err != nil {\n\t\treturn errors.Wrap(err, \"malformed orderer metadata in block\")\n\t}\n\n\t// Ensure the block's OrdererBlockMetadata matches the signature.\n\tif !proto.Equal(ordererMDFromBlock, ordererMD) {\n\t\treturn errors.Errorf(\"signature's OrdererBlockMetadata and OrdererBlockMetadata extracted from block do not match\")\n\t}\n","sourceCodeStart":404,"sourceCodeEnd":440,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/verifier.go#L404-L440","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: block with only 3 metadata slots\nblock.Metadata.Metadata = []([]byte){sigs, lastConf, txFilter} // -> error\n// after: include ORDERER metadata slot (index 3)\nblock.Metadata.Metadata = append(block.Metadata.Metadata, ordererMDBytes) // length == len(BlockMetadataIndex_name)","handlingStrategy":"validation","validationCode":"if len(block.Metadata.GetMetadata()) != len(cb.BlockMetadataIndex_name) {\n    return fmt.Errorf(\"block has %d metadata slots, need %d\",\n        len(block.Metadata.GetMetadata()), len(cb.BlockMetadataIndex_name))\n}","typeGuard":null,"tryCatchPattern":"if err := verifyProposal(prop); err != nil {\n    if strings.Contains(err.Error(), \"block metadata is of size\") {\n        // upgrade/fix block producer, force view change\n    }\n    return err\n}","preventionTips":["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"],"tags":["hyperledger-fabric","smartbft","block-metadata","version-skew"],"backgroundTag":"block-metadata-slot-count-mismatch","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}