{"record":{"id":"3478b930cab91986","repo":"hyperledger/fabric","slug":"nil-envelope-payload","errorCode":null,"errorMessage":"nil envelope payload","messagePattern":"nil envelope payload","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/tx/processor_factory.go","lineNumber":56,"sourceCode":"\t\t}\n\t}\n\treturn c.NewProcessor(txEnv)\n}\n\n// validateProtoAndConstructTxEnv attempts to unmarshal the bytes and prepare an instance of struct tx.Envelope\n// It returns an error of type `tx.InvalidErr` if the proto message is found to be invalid\nfunc validateProtoAndConstructTxEnv(txEnvelopeBytes []byte) (*tx.Envelope, error) {\n\ttxenv, err := protoutil.UnmarshalEnvelope(txEnvelopeBytes)\n\tif err != nil {\n\t\treturn nil, &tx.InvalidErr{\n\t\t\tActualErr:      err,\n\t\t\tValidationCode: peer.TxValidationCode_INVALID_OTHER_REASON,\n\t\t}\n\t}\n\n\tif len(txenv.Payload) == 0 {\n\t\treturn nil, &tx.InvalidErr{\n\t\t\tActualErr:      errors.New(\"nil envelope payload\"),\n\t\t\tValidationCode: peer.TxValidationCode_BAD_PAYLOAD,\n\t\t}\n\t}\n\n\tpayload, err := protoutil.UnmarshalPayload(txenv.Payload)\n\tif err != nil {\n\t\treturn nil, &tx.InvalidErr{\n\t\t\tActualErr:      err,\n\t\t\tValidationCode: peer.TxValidationCode_BAD_PAYLOAD,\n\t\t}\n\t}\n\n\tif payload.Header == nil {\n\t\treturn nil, &tx.InvalidErr{\n\t\t\tActualErr:      errors.New(\"nil payload header\"),\n\t\t\tValidationCode: peer.TxValidationCode_BAD_PAYLOAD,\n\t\t}\n\t}","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/tx/processor_factory.go#L38-L74","documentation":"validateProtoAndConstructTxEnv checks that the envelope's Payload bytes are present before unmarshalling. An empty payload means the envelope was signed/sent without a payload, so it cannot be parsed; it returns BAD_PAYLOAD. This is a defensive nil/empty check preceding protoutil.UnmarshalPayload.","triggerScenarios":"Creating a common.Envelope with Payload left nil/empty, or an envelope that lost its payload during serialization/transport corruption.","commonSituations":"Test code signing an empty envelope; network corruption or manual byte-slicing of envelopes; replaying truncated datagrams; clients that marshaled a nil Payload message.","solutions":["Ensure the envelope is built via protoutil.CreateSignedEnvelope (or Marshal of a populated Payload) so Payload bytes are non-empty.","Verify the source of the envelope bytes — re-marshal the full Envelope, not just header fields.","Add a client-side check len(env.Payload) > 0 before dispatching."],"exampleFix":"// before\nenv := &common.Envelope{Signature: sig}\n// after\npayloadBytes, _ := protoutil.Marshal(payload)\nenv := &common.Envelope{Payload: payloadBytes, Signature: sig}","handlingStrategy":"validation","validationCode":"if len(env.Payload) == 0 { return errors.New(\"envelope payload is empty\") }","typeGuard":"func hasPayload(env *common.Envelope) bool { return env != nil && len(env.Payload) > 0 }","tryCatchPattern":"// caller of CreateProcessor\n_, err := f.CreateProcessor(txEnv)\nvar ierr *tx.InvalidErr\nif errors.As(err, &ierr) && ierr.ValidationCode == peer.TxValidationCode_BAD_PAYLOAD {\n    // reject/move to failed-transactions log\n}","preventionTips":["Build envelopes only via protoutil.CreateSignedEnvelope.","Never sign or transmit envelopes constructed from unmarshalled partial bytes.","Verify byte integrity end-to-end when envelopes cross process boundaries."],"tags":["fabric","transaction-validation","payload"],"backgroundTag":"malformed-envelope","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"}