{"record":{"id":"843b3a3c28dea6b0","repo":"hyperledger/fabric","slug":"block-with-id-d-on-channel-s-does-not-have-m-843b3a","errorCode":null,"errorMessage":"Block with id [%d] on channel [%s] does not have metadata. Block not valid.","messagePattern":"Block with id \\[(.+?)\\] on channel \\[(.+?)\\] does not have metadata\\. Block not valid\\.","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/peer/gossip/mcs.go","lineNumber":150,"sourceCode":"\n\tblockSeqNum := block.Header.Number\n\tif seqNum != blockSeqNum {\n\t\treturn fmt.Errorf(\"Claimed seqNum is [%d] but actual seqNum inside block is [%d]\", seqNum, blockSeqNum)\n\t}\n\n\t// - Extract channelID and compare with chainID\n\tchannelID, err := protoutil.GetChannelIDFromBlock(block)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Failed getting channel id from block with id [%d] on channel [%s]: [%s]\", block.Header.Number, chainID, err)\n\t}\n\n\tif channelID != string(chainID) {\n\t\treturn fmt.Errorf(\"Invalid block's channel id. Expected [%s]. Given [%s]\", chainID, channelID)\n\t}\n\n\t// - Unmarshal medatada\n\tif block.Metadata == nil || len(block.Metadata.Metadata) == 0 {\n\t\treturn fmt.Errorf(\"Block with id [%d] on channel [%s] does not have metadata. Block not valid.\", block.Header.Number, chainID)\n\t}\n\n\tdataHash, err := protoutil.BlockDataHash(block.Data)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// - Verify that Header.DataHash is equal to the hash of block.Data\n\t// This is to ensure that the header is consistent with the data carried by this block\n\tif !bytes.Equal(dataHash, block.Header.DataHash) {\n\t\treturn fmt.Errorf(\"Header.DataHash is different from Hash(block.Data) for block with id [%d] on channel [%s]\", block.Header.Number, chainID)\n\t}\n\n\treturn s.verifyHeaderAndMetadata(channelID, block)\n}\n\nfunc (s *MSPMessageCryptoService) verifyHeaderAndMetadata(channelID string, block *pcommon.Block) error {\n\t// Get the policy manager for channelID\n\tcpm := s.channelPolicyManagerGetter.Manager(channelID)","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/peer/gossip/mcs.go#L132-L168","documentation":"VerifyBlock requires each block to carry metadata (block.Metadata with at least one metadata entry) because signatures and validation info live in the metadata section. A block missing metadata cannot be signed-verified so it is rejected as not valid.","triggerScenarios":"VerifyBlock called with block.Metadata == nil or block.Metadata.Metadata empty — typically a truncated or hand-constructed block, or a block from which metadata was stripped.","commonSituations":"Blocks synthesized in unit tests without metadata; corruption during block transfer; code that copies only Header/Data when cloning blocks.","solutions":["Ensure blocks are created/populated via protoutil block-construction helpers that set metadata","Re-fetch the block from the orderer or a committed source instead of the corrupt copy","In tests, populate block.Metadata (e.g. with a valid metadata signature array) before verification"],"exampleFix":"// before\nblock := &common.Block{Header: hdr, Data: data}\n// after\nblock := &common.Block{Header: hdr, Data: data, Metadata: &common.BlockMetadata{\n    Metadata: [][]byte{nil, {}, {}},\n}}","handlingStrategy":"type-guard","validationCode":"func hasMetadata(b *pcommon.Block) bool {\n    return b != nil && b.Metadata != nil && len(b.Metadata.Metadata) > 0\n}","typeGuard":"func hasMetadata(b *pcommon.Block) bool {\n    return b != nil && b.Metadata != nil && len(b.Metadata.Metadata) > 0\n}\n\nif !hasMetadata(block) {\n    return errors.New(\"block missing metadata; cannot verify\")\n}\nerr := cryptoService.VerifyBlock(chainID, seqNum, block)","tryCatchPattern":"if err := cryptoService.VerifyBlock(chainID, seqNum, block); err != nil {\n    if strings.Contains(err.Error(), \"does not have metadata\") {\n        log.Warnf(\"block %d on %s lacks metadata, rejecting\", seqNum, chainID)\n        return nil\n    }\n    return err\n}","preventionTips":["Build blocks only via protoutil helpers that populate metadata","When copying/cloning blocks, include the Metadata field","Reject headerless/metadata-less blocks at ingestion instead of at verification"],"tags":["fabric","gossip","block-validation"],"backgroundTag":"missing-block-metadata","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"}