{"record":{"id":"094e2ef689a677de","repo":"hyperledger/fabric","slug":"invalid-envelope-payload-can-t-be-nil","errorCode":null,"errorMessage":"Invalid envelope payload. can't be nil","messagePattern":"Invalid envelope payload\\. can't be nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"protoutil/commonutils.go","lineNumber":237,"sourceCode":"\t\treturn false\n\t}\n\n\tif payload.Header == nil {\n\t\treturn false\n\t}\n\n\thdr, err := UnmarshalChannelHeader(payload.Header.ChannelHeader)\n\tif err != nil {\n\t\treturn false\n\t}\n\n\treturn cb.HeaderType(hdr.Type) == cb.HeaderType_CONFIG\n}\n\n// ChannelHeader returns the *cb.ChannelHeader for a given *cb.Envelope.\nfunc ChannelHeader(env *cb.Envelope) (*cb.ChannelHeader, error) {\n\tif env == nil {\n\t\treturn nil, errors.New(\"Invalid envelope payload. can't be nil\")\n\t}\n\n\tenvPayload, err := UnmarshalPayload(env.Payload)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif envPayload.Header == nil {\n\t\treturn nil, errors.New(\"header not set\")\n\t}\n\n\tif envPayload.Header.ChannelHeader == nil {\n\t\treturn nil, errors.New(\"channel header not set\")\n\t}\n\n\tchdr, err := UnmarshalChannelHeader(envPayload.Header.ChannelHeader)\n\tif err != nil {\n\t\treturn nil, errors.WithMessage(err, \"error unmarshalling channel header\")","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/protoutil/commonutils.go#L219-L255","documentation":"ChannelHeader(env) extracts the *cb.ChannelHeader for an envelope by first unmarshaling its payload. If the *cb.Envelope argument itself is nil, the function returns 'Invalid envelope payload. can't be nil' rather than dereferencing it. It is the entry-level nil guard of a chain that can also fail later with 'header not set' or 'channel header not set'.","triggerScenarios":"Passing a nil *cb.Envelope to ChannelHeader, ChannelID, isConfig, ConfigChannelHeader, or ConfigEnvelopeFromBlock — e.g. an extraction step returned nil and was propagated unchecked, or a loop over empty block data.","commonSituations":"Processing blocks whose envelope extraction failed upstream (nil envelope error swallowed); map lookups or slices yielding nil envelopes; tooling iterating blocks from a partially-written ledger where an envelope slot is nil.","solutions":["Check env != nil before calling ChannelHeader or its wrappers (ChannelID, isConfig, etc.).","Fix the upstream producer of the nil envelope — usually a failed ExtractEnvelope/GetEnvelopeFromBlock whose error was ignored.","When iterating block data, skip or log entries that fail to decode instead of passing nil onward.","Wrap the call in error handling so 'Invalid envelope payload' distinguishes nil envelopes from real unmarshal failures in logs."],"exampleFix":"// before\nchdr, err := protoutil.ChannelHeader(env) // env may be nil\n// after\nif env == nil {\n    return errors.New(\"skipping block entry: no envelope\")\n}\nchdr, err := protoutil.ChannelHeader(env)","handlingStrategy":"type-guard","validationCode":"func channelHeaderSafe(env *cb.Envelope) (*cb.ChannelHeader, error) {\n    if env == nil {\n        return nil, errors.New(\"nil envelope\")\n    }\n    return protoutil.ChannelHeader(env)\n}","typeGuard":"func isEnvelope(e *cb.Envelope) bool {\n    return e != nil && len(e.Payload) > 0\n}","tryCatchPattern":"chdr, err := protoutil.ChannelHeader(env)\nif err != nil {\n    switch {\n    case err.Error() == \"Invalid envelope payload. can't be nil\":\n        return errors.New(\"caller passed nil envelope\")\n    case err.Error() == \"header not set\", err.Error() == \"channel header not set\":\n        return fmt.Errorf(\"envelope missing header fields: %w\", err)\n    }\n    return err\n}","preventionTips":["Never ignore errors from ExtractEnvelope/GetEnvelopeFromBlock — their nil results flow into ChannelHeader","Add a nil check at every block-iteration boundary before touching envelope helpers","Use isEnvelope-style guards in shared processing utilities","Log skipped/nil envelopes with block number to catch ledger corruption early"],"tags":["hyperledger-fabric","nil-check","envelope"],"backgroundTag":"nil-argument","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"}