{"record":{"id":"c874cb4fd7f993cb","repo":"hyperledger/fabric","slug":"nil-header","errorCode":null,"errorMessage":"nil header","messagePattern":"nil header","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/common/validation/msgvalidation.go","lineNumber":122,"sourceCode":"\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\n\t// will be in place.\n\tif cHdr.Epoch != 0 {\n\t\treturn errors.Errorf(\"invalid Epoch in ChannelHeader. Expected 0, got [%d]\", cHdr.Epoch)\n\t}\n\n\t// TODO: Validate version in cHdr.Version\n\n\treturn nil\n}\n\n// checks for a valid Header\nfunc validateCommonHeader(hdr *common.Header) (*common.ChannelHeader, *common.SignatureHeader, error) {\n\tif hdr == nil {\n\t\treturn nil, nil, errors.New(\"nil header\")\n\t}\n\n\tchdr, err := protoutil.UnmarshalChannelHeader(hdr.ChannelHeader)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tshdr, err := protoutil.UnmarshalSignatureHeader(hdr.SignatureHeader)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\terr = validateChannelHeader(chdr)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\terr = validateSignatureHeader(shdr)","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/common/validation/msgvalidation.go#L104-L140","documentation":"validateCommonHeader validates the common Header of a transaction and returns its parsed ChannelHeader and SignatureHeader. If the entire Header pointer is nil there is nothing to validate, so it returns this error before any field-level checks.","triggerScenarios":"ValidateTransaction or validateEndorserTransaction called with a payload whose Header is nil — typically when Payload.Header was never set in the envelope, or a test passes a nil header directly to validateCommonHeader.","commonSituations":"Clients building envelopes without attaching a Header; protobuf deserialization leaving Header nil for truncated payloads; test fixtures with minimal Payload structs; code paths that skip header assembly on error without aborting.","solutions":["Always populate Payload.Header (ChannelHeader + SignatureHeader) before signing and submitting the envelope","Check the client transaction-builder flow to ensure header assembly errors abort submission instead of producing a header-less payload","Fix test fixtures to construct a full Header via protoutil helpers","Validate envelope structure client-side (payload.Header != nil) before submit for clearer errors"],"exampleFix":"// before\npayload := &common.Payload{Data: cceBytes} // Header missing\n// after\npayload := &common.Payload{Header: &common.Header{ChannelHeader: chdrBytes, SignatureHeader: shdrBytes}, Data: cceBytes}","handlingStrategy":"type-guard","validationCode":"func hasHeader(payload *common.Payload) bool {\n    return payload != nil && payload.Header != nil\n}","typeGuard":"func headerReady(payload *common.Payload) bool {\n    return payload != nil && payload.Header != nil &&\n        len(payload.Header.ChannelHeader) > 0 && len(payload.Header.SignatureHeader) > 0\n}","tryCatchPattern":"if err != nil && err.Error() == \"nil header\" {\n    // payload.Header was nil: rebuild envelope with a complete Header before resubmitting\n}","preventionTips":["Always assemble Payload.Header (both ChannelHeader and SignatureHeader) before signing","Abort envelope construction if header assembly fails instead of continuing with nil","Use protoutil helpers to build payloads so Header cannot be omitted accidentally"],"tags":["hyperledger-fabric","validation","nil-argument","payload-header"],"backgroundTag":"nil-argument-validation","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"}