{"record":{"id":"3e788837d999aff3","repo":"hyperledger/fabric","slug":"no-header-in-payload","errorCode":null,"errorMessage":"no header in payload","messagePattern":"no header in payload","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/util.go","lineNumber":257,"sourceCode":"}\n\nfunc (ri *RequestInspector) unwrapReq(req []byte) (*request, error) {\n\tenvelope, err := protoutil.UnmarshalEnvelope(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn ri.unwrapReqFromEnvelop(envelope)\n}\n\nfunc (ri *RequestInspector) unwrapReqFromEnvelop(envelope *cb.Envelope) (*request, error) {\n\tpayload := &cb.Payload{}\n\tif err := proto.Unmarshal(envelope.Payload, payload); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed unmarshalling payload\")\n\t}\n\n\tif payload.Header == nil {\n\t\treturn nil, errors.Errorf(\"no header in payload\")\n\t}\n\n\tsigHdr := &cb.SignatureHeader{}\n\tif err := proto.Unmarshal(payload.Header.SignatureHeader, sigHdr); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif len(payload.Header.ChannelHeader) == 0 {\n\t\treturn nil, errors.New(\"no channel header in payload\")\n\t}\n\n\tchdr, err := protoutil.UnmarshalChannelHeader(payload.Header.ChannelHeader)\n\tif err != nil {\n\t\treturn nil, errors.WithMessage(err, \"error unmarshalling channel header\")\n\t}\n\n\treturn &request{\n\t\tchHdr:    chdr,","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/util.go#L239-L275","documentation":"After the payload decodes, unwrapReqFromEnvelop checks that payload.Header is set and returns 'no header in payload' when it is nil. Every fabric transaction payload must carry a common.Header (containing ChannelHeader and SignatureHeader); without it the request cannot be attributed to a channel or client. This is a structural validation error, not a deserialization failure.","triggerScenarios":"Submitting an envelope whose Payload was marshaled from a cb.Payload with Header left nil, or an empty payload that decodes to a zero-valued Payload.","commonSituations":"Hand-built transactions in tests or scripts that forget to attach protoutil.MakePayloadHeader; malformed requests injected via gossip/consensus; tools generating envelopes from templates missing the header.","solutions":["Construct payloads with protoutil with headers: use protoutil.CreateSignedEnvelope / MakeChannelHeader + MakeSignatureHeader and attach via MakePayload","Validate client-side before submitting: decode the envelope and assert Payload.Header != nil","Reject/fix the producer of header-less envelopes; check configtxlator decode output","If this comes from network input, treat it as a malformed-request attack and drop it"],"exampleFix":"// before\npayload := &cb.Payload{Data: data} // Header nil\n// after\nchdr := protoutil.MakeChannelHeader(cb.HeaderType_ENDORSER_TRANSACTION, 0, channelID, 0)\nsigHdr, _ := protoutil.MakeSignatureHeader(serializedCreator, nonce)\npHeader := protoutil.MakePayloadHeader(chdr, sigHdr)\npayload := &cb.Payload{Header: pHeader, Data: data}","handlingStrategy":"validation","validationCode":"func hasHeader(env *cb.Envelope) bool {\n    p := &cb.Payload{}\n    if env == nil || proto.Unmarshal(env.Payload, p) != nil {\n        return false\n    }\n    return p.Header != nil\n}","typeGuard":"func hasPayloadHeader(p *cb.Payload) bool { return p != nil && p.Header != nil }","tryCatchPattern":"req, err := unwrap(raw)\nif err != nil {\n    if strings.Contains(err.Error(), \"no header in payload\") {\n        return nil, fmt.Errorf(\"rejecting headerless payload: %w\", err)\n    }\n    return nil, err\n}","preventionTips":["Use protoutil.MakePayloadHeader / CreateSignedEnvelope to always attach a header","Validate envelope structure client-side before signing and submitting","Treat headerless inbound envelopes as malformed and drop them"],"tags":["hyperledger-fabric","smartbft","missing-header","payload-validation"],"backgroundTag":"missing-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"}