{"record":{"id":"3eae949332ce8839","repo":"hyperledger/fabric","slug":"invalid-block-on-channel-s-header-must-be-diff","errorCode":null,"errorMessage":"Invalid Block on channel [%s]. Header must be different from nil.","messagePattern":"Invalid Block on channel \\[(.+?)\\]\\. Header must be different from nil\\.","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/peer/gossip/mcs.go","lineNumber":130,"sourceCode":"\tmspIDRaw := []byte(sid.Mspid)\n\traw := append(mspIDRaw, sid.IdBytes...)\n\n\t// Hash\n\tdigest, err := s.hasher.Hash(raw, &bccsp.SHA256Opts{})\n\tif err != nil {\n\t\tmcsLogger.Errorf(\"Failed computing digest of serialized identity %s: [%s]\", peerIdentity, err)\n\t\treturn nil\n\t}\n\n\treturn digest\n}\n\n// VerifyBlock returns nil if the block is properly signed, and the claimed seqNum is the\n// sequence number that the block's header contains.\n// else returns error\nfunc (s *MSPMessageCryptoService) VerifyBlock(chainID common.ChannelID, seqNum uint64, block *pcommon.Block) error {\n\tif block.Header == nil {\n\t\treturn fmt.Errorf(\"Invalid Block on channel [%s]. Header must be different from nil.\", chainID)\n\t}\n\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","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/peer/gossip/mcs.go#L112-L148","documentation":"MSPMessageCryptoService.VerifyBlock validates gossip-received blocks against the channel MSP. The first check requires the block to carry a Header; a nil header means the block is malformed and cannot be authenticated. Fabric returns this formatted error naming the channel.","triggerScenarios":"VerifyBlock called (by gossip state/message validation) with a *pcommon.Block whose Header field is nil — typically a deserialization failure or a synthesized/empty block passed in by a caller.","commonSituations":"Corrupt block delivered over gossip; bug in code constructing blocks without headers; unmarshalling errors silently swallowed upstream so a zero-value Block reaches verification.","solutions":["Check upstream block unmarshalling — a failed proto.Unmarshal likely produced a headerless block","Verify the gossip payload source; re-fetch the block from orderer/committer","Add a nil-header guard where the block is created before handing it to VerifyBlock"],"exampleFix":"// before\nerr := cryptoService.VerifyBlock(channelID, seq, block)\n// after\nif block == nil || block.Header == nil {\n    return fmt.Errorf(\"block has no header; refusing verification\")\n}\nerr := cryptoService.VerifyBlock(channelID, seq, block)","handlingStrategy":"type-guard","validationCode":"func verifiableBlock(b *pcommon.Block) bool {\n    return b != nil && b.Header != nil\n}","typeGuard":"func hasHeader(b *pcommon.Block) bool {\n    return b != nil && b.Header != nil\n}\n\nif !hasHeader(block) {\n    return errors.New(\"cannot verify block: missing header\")\n}\nerr := cryptoService.VerifyBlock(chainID, seqNum, block)","tryCatchPattern":"if err := cryptoService.VerifyBlock(chainID, seqNum, block); err != nil {\n    if strings.Contains(err.Error(), \"Header must be different from nil\") {\n        log.Warnf(\"dropping malformed block %d on %s\", seqNum, chainID)\n        return nil\n    }\n    return err\n}","preventionTips":["Always unmarshal blocks with proto.Unmarshal and check the error before verification","Never pass zero-value common.Block structs to crypto services","Log block provenance to catch corrupt gossip payloads early"],"tags":["fabric","gossip","block-validation"],"backgroundTag":"nil-block-header","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"}