{"record":{"id":"e70c7becc5088241","repo":"hyperledger/fabric","slug":"failed-unmarshaling-ordererblockmetadata","errorCode":null,"errorMessage":"failed unmarshaling OrdererBlockMetadata","messagePattern":"failed unmarshaling OrdererBlockMetadata","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/verifier.go","lineNumber":279,"sourceCode":"\treturn nil\n}\n\nfunc (v *Verifier) verifyBlockDataAndMetadata(block *cb.Block, metadata []byte) ([]types.RequestInfo, error) {\n\tif block.Data == nil || len(block.Data.Data) == 0 {\n\t\treturn nil, errors.New(\"empty block data\")\n\t}\n\n\tif block.Metadata == nil || len(block.Metadata.Metadata) < len(cb.BlockMetadataIndex_name) {\n\t\treturn nil, errors.New(\"block metadata is either missing or contains too few entries\")\n\t}\n\n\tsignatureMetadata, err := protoutil.GetMetadataFromBlock(block, cb.BlockMetadataIndex_SIGNATURES)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tordererMetadataFromSignature := &cb.OrdererBlockMetadata{}\n\tif err := proto.Unmarshal(signatureMetadata.Value, ordererMetadataFromSignature); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed unmarshaling OrdererBlockMetadata\")\n\t}\n\n\t// Ensure the view metadata in the block signature and in the proposal are the same\n\n\tmetadataInBlock := &smartbftprotos.ViewMetadata{}\n\tif err := proto.Unmarshal(ordererMetadataFromSignature.ConsenterMetadata, metadataInBlock); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed unmarshaling smartbft metadata from block\")\n\t}\n\n\tmetadataFromProposal := &smartbftprotos.ViewMetadata{}\n\tif err := proto.Unmarshal(metadata, metadataFromProposal); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed unmarshaling smartbft metadata from proposal\")\n\t}\n\n\tif !proto.Equal(metadataInBlock, metadataFromProposal) {\n\t\treturn nil, errors.Errorf(\n\t\t\t\"expected metadata in block to be [view_id:%d latest_sequence:%d] but got [view_id:%d latest_sequence:%d]\",\n\t\t\tmetadataFromProposal.GetViewId(), metadataFromProposal.GetLatestSequence(),","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/verifier.go#L261-L297","documentation":"The SIGNATURES metadata entry of the proposed block must contain an OrdererBlockMetadata protobuf. If proto.Unmarshal of signatureMetadata.Value into OrdererBlockMetadata fails, the verifier wraps the error, meaning the orderer-level metadata in the block is corrupted or of the wrong shape.","triggerScenarios":"GetMetadataFromBlock succeeds but the SIGNATURES metadata Value bytes are not a valid OrdererBlockMetadata — wrong metadata index populated, corrupted bytes, or metadata written by a different component/version.","commonSituations":"Custom code writing raw bytes into the SIGNATURES metadata slot; version mismatch where the OrdererBlockMetadata schema changed; corrupted proposal from WAL/network; metadata truncation during transport or persistence.","solutions":["Rebuild the block metadata using protoutil/fabric orderer helpers so SIGNATURES carries a valid OrdererBlockMetadata","Confirm all nodes use a compatible fabric version with the same OrdererBlockMetadata schema","Inspect the offending metadata bytes (log base64) to identify corruption source","Discard the malformed proposal and re-propose from current leader state"],"exampleFix":"// before: raw view metadata written into SIGNATURES slot\nmetadata[cb.BlockMetadataIndex_SIGNATURES] = consenterMetadataRaw\n// after: wrap in OrdererBlockMetadata\nobm := &cb.OrdererBlockMetadata{ConsenterMetadata: consenterMetadataRaw}\nval, _ := proto.Marshal(obm)\nmetadata[cb.BlockMetadataIndex_SIGNATURES] = &cb.Metadata{Value: val}","handlingStrategy":"try-catch","validationCode":"sm := protoutil.GetMetadataFromBlock(block, cb.BlockMetadataIndex_SIGNATURES)\nobm := &cb.OrdererBlockMetadata{}\nif err := proto.Unmarshal(sm.Value, obm); err != nil { return fmt.Errorf(\"invalid orderer metadata\") }","typeGuard":"func validOrdererMetadata(b *cb.Block) bool {\n    sm, err := protoutil.GetMetadataFromBlock(b, cb.BlockMetadataIndex_SIGNATURES)\n    if err != nil { return false }\n    return proto.Unmarshal(sm.Value, &cb.OrdererBlockMetadata{}) == nil\n}","tryCatchPattern":"if _, err := verifier.VerifyProposal(...); err != nil && strings.Contains(err.Error(), \"failed unmarshaling OrdererBlockMetadata\") {\n    logger.Warn(\"corrupted orderer metadata in proposal; request re-proposal\")\n}","preventionTips":["Write SIGNATURES metadata only via fabric orderer helpers","Keep fabric versions consistent across the cluster","Log offending metadata bytes (base64) for corruption diagnosis","Validate metadata decodability before accepting proposals"],"tags":["smartbft","fabric","protobuf","metadata"],"backgroundTag":"metadata-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"}