hyperledger/fabric · error

nil payload header

Error message

nil payload header

What it means

validateProtoAndConstructTxEnv requires payload.Header to be non-nil. A Payload whose Header is unset cannot be routed (no channel, type, or txid), so it is rejected with BAD_PAYLOAD. This check follows successful Payload unmarshalling.

Source

Thrown at core/tx/processor_factory.go:71

	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,
		}
	}

	if len(payload.Header.ChannelHeader) == 0 {
		return nil, &tx.InvalidErr{
			ActualErr:      errors.New("nil payload channel header"),
			ValidationCode: peer.TxValidationCode_BAD_PAYLOAD,
		}
	}

	chdr, err := protoutil.UnmarshalChannelHeader(payload.Header.ChannelHeader)
	if err != nil {
		return nil, &tx.InvalidErr{
			ActualErr:      err,
			ValidationCode: peer.TxValidationCode_BAD_PAYLOAD,
		}
	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Set payload.Header = &common.Header{ChannelHeader: chdrBytes, SignatureHeader: shdrBytes} before marshaling.
  2. Use protoutil.MakeChannelHeader + protoutil.MakePayloadHeader helpers to build a complete header.
  3. Check payload.Header != nil before submit/marshal in client code.

Example fix

// before
payload := &common.Payload{Data: cceBytes}
// after
payload := &common.Payload{Header: protoutil.MakePayloadHeader(chdr, shdr), Data: cceBytes}
Defensive patterns

Strategy: validation

Validate before calling

if payload.Header == nil { return errors.New("payload header is nil") }

Type guard

func hasHeader(p *common.Payload) bool { return p != nil && p.Header != nil }

Prevention

When it happens

Trigger: Unmarshalled payload bytes that describe only Data with no Header — e.g. payload := &common.Payload{Data: data} marshaled without setting Header.

Common situations: Hand-assembled payloads in tests; payloads built before ChannelHeader/SignatureHeader construction failed or was skipped; older clients producing header-less payloads after a protocol change.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/93995c792fbe0efa. Report an issue: GitHub.