{"record":{"id":"b76fe22394abba93","repo":"hyperledger/fabric","slug":"payload-header-is-nil","errorCode":null,"errorMessage":"payload header is nil","messagePattern":"payload header is nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gossip/privdata/coordinator.go","lineNumber":425,"sourceCode":"\ttxRWSet      *rwsetutil.TxRwSet\n}\n\n// getTxInfoFromTransactionBytes parses a transaction and returns info required for private data retrieval\nfunc getTxInfoFromTransactionBytes(envBytes []byte) (*txInfo, error) {\n\ttxInfo := &txInfo{}\n\tenv, err := protoutil.GetEnvelopeFromBlock(envBytes)\n\tif err != nil {\n\t\tlogger.Warningf(\"Invalid envelope: %s\", err)\n\t\treturn nil, err\n\t}\n\n\tpayload, err := protoutil.UnmarshalPayload(env.Payload)\n\tif err != nil {\n\t\tlogger.Warningf(\"Invalid payload: %s\", err)\n\t\treturn nil, err\n\t}\n\tif payload.Header == nil {\n\t\terr := errors.New(\"payload header is nil\")\n\t\tlogger.Warningf(\"Invalid tx: %s\", err)\n\t\treturn nil, err\n\t}\n\n\tchdr, err := protoutil.UnmarshalChannelHeader(payload.Header.ChannelHeader)\n\tif err != nil {\n\t\tlogger.Warningf(\"Invalid channel header: %s\", err)\n\t\treturn nil, err\n\t}\n\ttxInfo.channelID = chdr.ChannelId\n\ttxInfo.txID = chdr.TxId\n\n\tif chdr.Type != int32(common.HeaderType_ENDORSER_TRANSACTION) {\n\t\terr := errors.New(\"header type is not an endorser transaction\")\n\t\tlogger.Debugf(\"Invalid transaction type: %s\", err)\n\t\treturn nil, err\n\t}\n","sourceCodeStart":407,"sourceCodeEnd":443,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/gossip/privdata/coordinator.go#L407-L443","documentation":"getTxInfoFromTransactionBytes unwraps the envelope's payload and requires payload.Header to extract the channel header and compute the tx id. A payload without a header is invalid — the tx cannot be identified, so the function logs a warning and returns this error, causing the tx to be skipped from the block's private-data info.","triggerScenarios":"StoreBlock -> getTxPvtdataInfoFromBlock -> getTxInfoFromTransactionBytes where a tx envelope's payload unmarshals fine but its Header field is nil — a malformed or maliciously crafted envelope inside block.Data.Data.","commonSituations":"Corrupted blocks from an untrusted gossip source; envelopes constructed manually in tests without headers; garbage bytes that happen to decode as a payload; truncated chaincode submission payloads.","solutions":["Obtain blocks only from trusted sources (orderer / validated peers) so envelopes carry proper headers","Drop or re-fetch the malformed block; fabric skips the offending tx but repeated occurrences indicate a corrupt source","Fix envelope construction to include payload.Header (ChannelHeader + SignatureHeader) in tests/tools","Validate envelopes (protoutil.UnmarshalEnvelope + header presence) before ingesting"],"exampleFix":"// before\nenv.Payload = marshal(&common.Payload{Data: txBytes}) // no header\n// after\nenv.Payload = marshal(&common.Payload{\n    Header: &common.PayloadHeader{\n        ChannelHeader:   marshal(chdr),\n        SignatureHeader: marshal(shdr),\n    },\n    Data: txBytes,\n})","handlingStrategy":"validation","validationCode":"env, err := protoutil.UnmarshalEnvelope(txEnvBytes)\nif err != nil { return err }\npayload, err := protoutil.UnmarshalPayload(env.Payload)\nif err != nil { return err }\nif payload.Header == nil {\n    return errors.New(\"envelope payload has no header; skipping tx\")\n}","typeGuard":"func envelopeHasHeader(txEnvBytes []byte) bool {\n    env, err := protoutil.UnmarshalEnvelope(txEnvBytes)\n    if err != nil { return false }\n    payload, err := protoutil.UnmarshalPayload(env.Payload)\n    if err != nil { return false }\n    return payload.Header != nil\n}","tryCatchPattern":null,"preventionTips":["Always populate Payload.Header (ChannelHeader + SignatureHeader) when crafting envelopes","Treat headerless txs as skippable; repeated hits indicate a corrupt block source","Validate envelopes before adding them to test blocks","Accept blocks only from trusted orderer/peer sources"],"tags":["gossip","privdata","envelope","malformed-tx"],"backgroundTag":"malformed-payload-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"}