hyperledger/fabric · error

error marshaling ChaincodeProposalPayload: proto: Marshal ca

Error message

error marshaling ChaincodeProposalPayload: proto: Marshal called with nil

What it means

GetBytesChaincodeProposalPayload explicitly returns this pre-computed error when called with a nil *peer.ChaincodeProposalPayload, mimicking proto.Marshal's nil error text. It is a guard added because marshaling nil would otherwise fail confusingly inside the library.

Source

Thrown at protoutil/proputils.go:137

		ChaincodeId: ccid,
	}
	cActBytes, err := proto.Marshal(cAct)
	if err != nil {
		return nil, errors.Wrap(err, "error marshaling ChaincodeAction")
	}

	prp := &peer.ProposalResponsePayload{
		Extension:    cActBytes,
		ProposalHash: hash,
	}
	prpBytes, err := proto.Marshal(prp)
	return prpBytes, errors.Wrap(err, "error marshaling ProposalResponsePayload")
}

// GetBytesChaincodeProposalPayload gets the chaincode proposal payload
func GetBytesChaincodeProposalPayload(cpp *peer.ChaincodeProposalPayload) ([]byte, error) {
	if cpp == nil {
		return nil, errors.New("error marshaling ChaincodeProposalPayload: proto: Marshal called with nil")
	}
	cppBytes, err := proto.Marshal(cpp)
	return cppBytes, errors.Wrap(err, "error marshaling ChaincodeProposalPayload")
}

// GetBytesResponse gets the bytes of Response
func GetBytesResponse(res *peer.Response) ([]byte, error) {
	if res == nil {
		return nil, errors.New("error marshaling Response: proto: Marshal called with nil")
	}
	resBytes, err := proto.Marshal(res)
	return resBytes, errors.Wrap(err, "error marshaling Response")
}

// GetBytesChaincodeEvent gets the bytes of ChaincodeEvent
func GetBytesChaincodeEvent(event *peer.ChaincodeEvent) ([]byte, error) {
	if event == nil {
		return nil, errors.New("error marshaling ChaincodeEvent: proto: Marshal called with nil")

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Check the error from proposal-creation functions before using the payload pointer
  2. Ensure GetBytesProposalPayloadForTx receives a non-nil cpp built from a successful CreateChaincodeProposal call
  3. Add a nil check at the call site before invoking GetBytesChaincodeProposalPayload

Example fix

// before
cppBytes, err := protoutil.GetBytesChaincodeProposalPayload(proposal.Payload) // proposal is nil after earlier error ignored
// after
if proposal == nil || proposal.Payload == nil {
    return errors.New("proposal or payload missing; check earlier proposal-creation error")
}
cppBytes, err := protoutil.GetBytesChaincodeProposalPayload(proposal.Payload)
Defensive patterns

Strategy: type-guard

Validate before calling

if proposal == nil || proposal.Payload == nil {
	return errors.New("proposal/payload missing — check the error from CreateChaincodeProposal")
}
cppBytes, err := protoutil.GetBytesChaincodeProposalPayload(proposal.Payload)

Type guard

func isProposalPayloadReady(proposal *peer.Proposal) bool {
	return proposal != nil && proposal.Payload != nil
}

Try / catch

cppBytes, err := protoutil.GetBytesChaincodeProposalPayload(cpp)
if err != nil {
	if strings.Contains(err.Error(), "Marshal called with nil") {
		return fmt.Errorf("proposal payload never created; upstream error swallowed: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Calling GetBytesChaincodeProposalPayload(nil), or via callers GetBytesProposalPayloadForTx / prepareTransaction when the upstream proposal payload was never constructed (e.g. proposal creation was skipped on error and its nil result was passed through).

Common situations: Ignoring the error from CreateChaincodeProposal and continuing with a nil payload; test harnesses assembling transactions without a proposal; SDK code paths where proposal generation silently failed.

Related errors


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