{"record":{"id":"d0885bde81809eee","repo":"hyperledger/fabric","slug":"nil-channelheader-provided","errorCode":null,"errorMessage":"nil ChannelHeader provided","messagePattern":"nil ChannelHeader provided","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/common/validation/msgvalidation.go","lineNumber":90,"sourceCode":"\n\t// ensure that there is a nonce\n\tif len(sHdr.Nonce) == 0 {\n\t\treturn errors.New(\"invalid nonce specified in the header\")\n\t}\n\n\t// ensure that there is a creator\n\tif len(sHdr.Creator) == 0 {\n\t\treturn errors.New(\"invalid creator specified in the header\")\n\t}\n\n\treturn nil\n}\n\n// checks for a valid ChannelHeader\nfunc validateChannelHeader(cHdr *common.ChannelHeader) error {\n\t// check for nil argument\n\tif cHdr == nil {\n\t\treturn errors.New(\"nil ChannelHeader provided\")\n\t}\n\n\t// validate the header type\n\tswitch common.HeaderType(cHdr.Type) {\n\tcase common.HeaderType_ENDORSER_TRANSACTION:\n\tcase common.HeaderType_CONFIG_UPDATE:\n\tcase common.HeaderType_CONFIG:\n\tdefault:\n\t\treturn errors.Errorf(\"invalid header type %s\", common.HeaderType(cHdr.Type))\n\t}\n\n\tputilsLogger.Debugf(\"validateChannelHeader info: header type %d\", common.HeaderType(cHdr.Type))\n\n\t// TODO: validate channelID in cHdr.ChannelID\n\n\t// Validate epoch in cHdr.Epoch\n\t// Currently we enforce that Epoch is 0.\n\t// TODO: This check will be modified once the Epoch management","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/common/validation/msgvalidation.go#L72-L108","documentation":"validateChannelHeader checks the ChannelHeader of a transaction. A nil ChannelHeader means the header was absent or failed protobuf unmarshalling in validateCommonHeader's caller path, so fields like type, channel ID, and epoch cannot be validated. The function rejects it up front.","triggerScenarios":"validateCommonHeader -> validateChannelHeader called with a Header whose ChannelHeader bytes are nil/empty, or UnmarshalChannelHeader producing a nil pointer for malformed input.","commonSituations":"SDK-built envelopes missing the channel header; protobuf corruption during storage/transport; hand-built messages in tests omitting ChannelHeader; reading truncated blocks.","solutions":["Ensure Header.ChannelHeader is populated and marshalled (type, ChannelID, TxId, Epoch) when building the transaction","Re-marshal/rebuild the envelope client-side if bytes may have been corrupted in transit","Check UnmarshalChannelHeader error handling upstream — surface it before validation","In tests, build headers with protoutil helpers (e.g. protoutil.MakeChannelHeader) instead of raw structs"],"exampleFix":"// before\nhdr := &common.Header{SignatureHeader: shdrBytes} // ChannelHeader missing\n// after\nchdr := protoutil.MakeChannelHeader(common.HeaderType_ENDORSER_TRANSACTION, 0, channelID, txid)\nhdr := &common.Header{ChannelHeader: protoutil.MarshalOrPanic(chdr), SignatureHeader: shdrBytes}","handlingStrategy":"validation","validationCode":"func channelHeaderPresent(hdr *common.Header) bool {\n    return hdr != nil && len(hdr.ChannelHeader) > 0\n}","typeGuard":"func channelHeaderValid(hdr *common.Header) bool {\n    if hdr == nil || len(hdr.ChannelHeader) == 0 {\n        return false\n    }\n    _, err := protoutil.UnmarshalChannelHeader(hdr.ChannelHeader)\n    return err == nil\n}","tryCatchPattern":"if err != nil && err.Error() == \"nil ChannelHeader provided\" {\n    // rebuild envelope with a marshalled ChannelHeader; do not retry as-is\n}","preventionTips":["Always attach a marshalled ChannelHeader to Payload.Header","Use protoutil.MakeChannelHeader instead of hand-rolled structs","Handle UnmarshalChannelHeader errors before proceeding to validation"],"tags":["hyperledger-fabric","validation","channel-header","protobuf"],"backgroundTag":"malformed-transaction-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"}