hyperledger/fabric · error

error marshaling ChaincodeHeaderExtension

Error message

error marshaling ChaincodeHeaderExtension

What it means

CreateChaincodeProposalWithTxIDNonceAndTransient builds the ChaincodeHeaderExtension (holding the chaincode ID) and protobuf-marshals it. This error wraps a proto.Marshal failure on that extension. In practice proto.Marshal of a well-formed ChaincodeHeaderExtension virtually never fails, so this indicates a nil cis / cis.ChaincodeSpec input.

Source

Thrown at protoutil/proputils.go:65

	if err != nil {
		return nil, "", err
	}

	// compute txid unless provided by tests
	if txid == "" {
		txid = ComputeTxID(nonce, creator)
	}

	return CreateChaincodeProposalWithTxIDNonceAndTransient(txid, typ, channelID, cis, nonce, creator, transientMap)
}

// CreateChaincodeProposalWithTxIDNonceAndTransient creates a proposal from
// given input
func CreateChaincodeProposalWithTxIDNonceAndTransient(txid string, typ common.HeaderType, channelID string, cis *peer.ChaincodeInvocationSpec, nonce, creator []byte, transientMap map[string][]byte) (*peer.Proposal, string, error) {
	ccHdrExt := &peer.ChaincodeHeaderExtension{ChaincodeId: cis.ChaincodeSpec.ChaincodeId}
	ccHdrExtBytes, err := proto.Marshal(ccHdrExt)
	if err != nil {
		return nil, "", errors.Wrap(err, "error marshaling ChaincodeHeaderExtension")
	}

	cisBytes, err := proto.Marshal(cis)
	if err != nil {
		return nil, "", errors.Wrap(err, "error marshaling ChaincodeInvocationSpec")
	}

	ccPropPayload := &peer.ChaincodeProposalPayload{Input: cisBytes, TransientMap: transientMap}
	ccPropPayloadBytes, err := proto.Marshal(ccPropPayload)
	if err != nil {
		return nil, "", errors.Wrap(err, "error marshaling ChaincodeProposalPayload")
	}

	// TODO: epoch is now set to zero. This must be changed once we
	// get a more appropriate mechanism to handle it in.
	var epoch uint64

	hdr := &common.Header{

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure cis is non-nil with cis.ChaincodeSpec.ChaincodeId populated before calling
  2. Build the spec with &peer.ChaincodeInvocationSpec{ChaincodeSpec: &peer.ChaincodeSpec{ChaincodeId: ccid, ...}}
  3. Align github.com/hyperledger/fabric-protos-go versions between your code and fabric

Example fix

// before
proposal, _, err := protoutil.CreateChaincodeProposalWithTransient(common.HeaderType_ENDORSER_TRANSACTION, "ch", nil, creator, transient) // nil CIS
// after
cis := &peer.ChaincodeInvocationSpec{ChaincodeSpec: &peer.ChaincodeSpec{ChaincodeId: &peer.ChaincodeID{Name: "mycc"}}}
proposal, _, err := protoutil.CreateChaincodeProposalWithTransient(common.HeaderType_ENDORSER_TRANSACTION, "ch", cis, creator, transient)
Defensive patterns

Strategy: validation

Validate before calling

if cis == nil || cis.ChaincodeSpec == nil || cis.ChaincodeSpec.ChaincodeId == nil {
	return errors.New("ChaincodeInvocationSpec with ChaincodeSpec.ChaincodeId is required")
}

Type guard

func validCIS(cis *peer.ChaincodeInvocationSpec) bool {
	return cis != nil && cis.ChaincodeSpec != nil && cis.ChaincodeSpec.ChaincodeId != nil && cis.ChaincodeSpec.ChaincodeId.Name != ""
}

Try / catch

proposal, txid, err := protoutil.CreateChaincodeProposalWithTransient(htype, channelID, cis, creator, transient)
if err != nil {
	return fmt.Errorf("proposal creation failed: %w", err) // includes marshal wrap message
}

Prevention

When it happens

Trigger: Calling CreateChaincodeProposalWithTxIDNonceAndTransient (or its wrappers CreateChaincodeProposalWithTransient, CreateChaincodeProposalWithTxIDAndTransient, CreateProposalFromCISAndTxid, ConstructSignedTxEnv) with cis == nil or cis.ChaincodeSpec == nil, which panics on the next line; a marshal failure would only occur with a corrupt protobuf registry/version mismatch of the peer proto package.

Common situations: Constructing proposals in SDK/CLI code where the ChaincodeInvocationSpec was forgotten or built without ChaincodeSpec; mixing incompatible github.com/hyperledger/fabric-protos versions with fabric.

Related errors


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