hyperledger/fabric · error
nil envelope payload
Error message
nil envelope payload
What it means
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.
Source
Thrown at core/tx/processor_factory.go:56
}
}
return c.NewProcessor(txEnv)
}
// validateProtoAndConstructTxEnv attempts to unmarshal the bytes and prepare an instance of struct tx.Envelope
// It returns an error of type `tx.InvalidErr` if the proto message is found to be invalid
func validateProtoAndConstructTxEnv(txEnvelopeBytes []byte) (*tx.Envelope, error) {
txenv, err := protoutil.UnmarshalEnvelope(txEnvelopeBytes)
if err != nil {
return nil, &tx.InvalidErr{
ActualErr: err,
ValidationCode: peer.TxValidationCode_INVALID_OTHER_REASON,
}
}
if len(txenv.Payload) == 0 {
return nil, &tx.InvalidErr{
ActualErr: errors.New("nil envelope payload"),
ValidationCode: peer.TxValidationCode_BAD_PAYLOAD,
}
}
payload, err := protoutil.UnmarshalPayload(txenv.Payload)
if err != nil {
return nil, &tx.InvalidErr{
ActualErr: err,
ValidationCode: peer.TxValidationCode_BAD_PAYLOAD,
}
}
if payload.Header == nil {
return nil, &tx.InvalidErr{
ActualErr: errors.New("nil payload header"),
ValidationCode: peer.TxValidationCode_BAD_PAYLOAD,
}
}View on GitHub (pinned to 2736b63f8f)
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.
Example fix
// before
env := &common.Envelope{Signature: sig}
// after
payloadBytes, _ := protoutil.Marshal(payload)
env := &common.Envelope{Payload: payloadBytes, Signature: sig} Defensive patterns
Strategy: validation
Validate before calling
if len(env.Payload) == 0 { return errors.New("envelope payload is empty") } Type guard
func hasPayload(env *common.Envelope) bool { return env != nil && len(env.Payload) > 0 } Try / catch
// caller of CreateProcessor
_, err := f.CreateProcessor(txEnv)
var ierr *tx.InvalidErr
if errors.As(err, &ierr) && ierr.ValidationCode == peer.TxValidationCode_BAD_PAYLOAD {
// reject/move to failed-transactions log
} Prevention
- 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.
When it happens
Trigger: Creating a common.Envelope with Payload left nil/empty, or an envelope that lost its payload during serialization/transport corruption.
Common situations: Test code signing an empty envelope; network corruption or manual byte-slicing of envelopes; replaying truncated datagrams; clients that marshaled a nil Payload message.
Related errors
- nil payload header
- nil payload channel header
- error unmarshalling ChaincodeHeaderExtension
- nil ChaincodeId in header extension
- nil ChaincodeId in ChaincodeAction
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/3478b930cab91986.
Report an issue: GitHub.