hyperledger/fabric · error

empty header extension

Error message

empty header extension

What it means

unmarshalEndorserTx parses a transaction envelope's channel header extension to extract chaincode header extension data (chaincode ID, etc.). If txenv.ChannelHeader.Extension is empty there is nothing to parse, so this error is thrown before attempting unmarshalling.

Source

Thrown at core/tx/endorser/parser.go:44

// EndorserTx represents a parsed common.Envelope protobuf
type EndorserTx struct {
	ComputedTxID string
	ChannelID    string
	ChaincodeID  *peer.ChaincodeID
	Creator      []byte
	Response     *peer.Response
	Events       []byte
	Results      []byte
	Endorsements []*peer.Endorsement
	Type         int32
	Version      int32
	Epoch        uint64
	Nonce        []byte
}

func unmarshalEndorserTx(txenv *tx.Envelope) (*EndorserTx, error) {
	if len(txenv.ChannelHeader.Extension) == 0 {
		return nil, errors.New("empty header extension")
	}

	hdrExt, err := protoutil.UnmarshalChaincodeHeaderExtension(
		txenv.ChannelHeader.Extension,
	)
	if err != nil {
		return nil, err
	}

	if len(txenv.Data) == 0 {
		return nil, errors.New("nil payload data")
	}

	tx, err := protoutil.UnmarshalTransaction(txenv.Data)
	if err != nil {
		return nil, err
	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure the envelope being parsed is an endorser transaction (type ENDORSER_TRANSACTION) with a populated ChannelHeader.Extension
  2. Fix client SDK payload construction to include the ChaincodeHeaderExtension
  3. Check the transaction type before calling UnmarshalEndorserTxAndValidate

Example fix

// before
protoutil.UnmarshalChaincodeHeaderExtension(txenv.ChannelHeader.Extension) // panics/errors on empty
// after
if txenv.ChannelHeader != nil && len(txenv.ChannelHeader.Extension) == 0 {
    return nil, errors.New("empty header extension")
}
Defensive patterns

Strategy: validation

Validate before calling

// before parsing, check transaction type and extension presence
if ch, _ := txEnvelope.GetChannelHeader(); ch == nil || len(ch.Extension) == 0 {
    return errors.New("envelope lacks channel header extension")
}

Type guard

func hasChannelHeaderExtension(env *common.Envelope) bool {
    ch, err := protoutil.ChannelHeader(env.Payload)
    return err == nil && ch != nil && len(ch.Extension) > 0
}

Try / catch

tx, err := tx.UnmarshalEndorserTxAndValidate(env)
if err != nil {
    if strings.Contains(err.Error(), "empty header extension") {
        // not an endorser tx: skip or route to correct parser
    }
    return err
}

Prevention

When it happens

Trigger: Calling UnmarshalEndorserTxAndValidate with an envelope whose ChannelHeader has no Extension bytes — e.g. a config or non-endorser transaction passed to an endorser-transaction parser.

Common situations: Passing a chaincode config-update or non-endorser envelope to the parser; envelope built incorrectly by client SDK; wrong transaction type routed to endorser validation.

Related errors


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