{"record":{"id":"2e28bb659a45bc20","repo":"hyperledger/fabric","slug":"malformed-orderer-metadata-in-block","errorCode":null,"errorMessage":"malformed orderer metadata in block","messagePattern":"malformed orderer metadata in block","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/verifier.go","lineNumber":433,"sourceCode":"\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\n\treturn nil\n}\n\ntype consenterVerifier struct {\n\tlogger        *flogging.FabricLogger\n\tchannel       string\n\tpolicyManager policies.Manager\n}\n\n// Evaluate evaluates signed data and returns no error if signature is valid and satisfies the policy\nfunc (cv *consenterVerifier) Evaluate(signatureSet []*protoutil.SignedData) error {","sourceCodeStart":415,"sourceCodeEnd":451,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/verifier.go#L415-L451","documentation":"verifySignatureIsBoundToProposal successfully unmarshalled the block's SIGNATURES metadata but then failed to unmarshal signatureMetadata.Value into cb.OrdererBlockMetadata. The Value bytes inside the signature metadata are corrupt or were written by a component that does not serialize OrdererBlockMetadata correctly.","triggerScenarios":"VerifyConsenterSig called on a block where the unmarshalled cb.Metadata.Value field is not a valid serialized cb.OrdererBlockMetadata message.","commonSituations":"Blocks produced by older Fabric consensus (e.g. etcdraft-style metadata) fed into a SmartBFT channel; corrupted block store; custom block producers/test harnesses writing wrong Value bytes.","solutions":["Ensure the block originates from a SmartBFT-consensus orderer of a compatible version","Restore the block from a peer/other orderer or from backup","Inspect the wrapped proto error to identify the malformed field","If testing, fix the block-building code to serialize cb.OrdererBlockMetadata into Value"],"exampleFix":"// before: hand-crafted metadata in tests\nsigMeta.Value = []byte(\"not-a-proto\")\n// after\nobm := &cb.OrdererBlockMetadata{ConsenterMetadata: consenterMD}\nval, _ := proto.Marshal(obm)\nsigMeta.Value = val","handlingStrategy":"validation","validationCode":"sigMD, err := protoutil.GetMetadataFromBlock(blk, cb.BlockMetadataIndex_SIGNATURES)\nif err != nil { return err }\nobm := &cb.OrdererBlockMetadata{}\nif err := proto.Unmarshal(sigMD.Value, obm); err != nil {\n    return fmt.Errorf(\"invalid OrdererBlockMetadata in block %d: %w\", blk.Header.Number, err)\n}","typeGuard":"func hasOrdererBlockMetadata(m *cb.Metadata) bool {\n    if m == nil || len(m.Value) == 0 { return false }\n    obm := &cb.OrdererBlockMetadata{}\n    return proto.Unmarshal(m.Value, obm) == nil\n}","tryCatchPattern":"if err := verifier.VerifyConsenterSig(blk, sig); err != nil {\n    if strings.Contains(err.Error(), \"malformed orderer metadata in block\") {\n        log.Warnf(\"rejecting block %d: %v\", blk.Header.Number, err)\n        return errRejectBlock\n    }\n    return err\n}","preventionTips":["Only accept blocks from SmartBFT orderers writing OrdererBlockMetadata","Serialize all metadata with proto.Marshal in custom tooling/tests","Pin consistent Fabric versions across the ordering service","Validate block contents with protoutil helpers before consensus verification"],"tags":["smartbft","consensus","protobuf","orderer-metadata"],"backgroundTag":"protobuf-unmarshal-failed","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"}