hyperledger/fabric · error

error unmarshalling ChaincodeProposalPayload

Error message

error unmarshalling ChaincodeProposalPayload

What it means

UnmarshalChaincodeProposalPayload wraps proto.Unmarshal failures of peer.ChaincodeProposalPayload bytes with this message. It is returned when the proposal payload bytes are malformed or of a different type. Callers typically get these bytes from a SignedProposal.ProposalPayload, so corruption or wrong-level extraction triggers it.

Source

Thrown at protoutil/unmarshalers.go:172

// UnmarshalTransaction unmarshals bytes to a Transaction
func UnmarshalTransaction(txBytes []byte) (*peer.Transaction, error) {
	tx := &peer.Transaction{}
	err := proto.Unmarshal(txBytes, tx)
	return tx, errors.Wrap(err, "error unmarshalling Transaction")
}

// UnmarshalChaincodeActionPayload unmarshals bytes to a ChaincodeActionPayload
func UnmarshalChaincodeActionPayload(capBytes []byte) (*peer.ChaincodeActionPayload, error) {
	cap := &peer.ChaincodeActionPayload{}
	err := proto.Unmarshal(capBytes, cap)
	return cap, errors.Wrap(err, "error unmarshalling ChaincodeActionPayload")
}

// UnmarshalChaincodeProposalPayload unmarshals bytes to a ChaincodeProposalPayload
func UnmarshalChaincodeProposalPayload(bytes []byte) (*peer.ChaincodeProposalPayload, error) {
	cpp := &peer.ChaincodeProposalPayload{}
	err := proto.Unmarshal(bytes, cpp)
	return cpp, errors.Wrap(err, "error unmarshalling ChaincodeProposalPayload")
}

// UnmarshalTxReadWriteSet unmarshals bytes to a TxReadWriteSet
func UnmarshalTxReadWriteSet(bytes []byte) (*rwset.TxReadWriteSet, error) {
	rws := &rwset.TxReadWriteSet{}
	err := proto.Unmarshal(bytes, rws)
	return rws, errors.Wrap(err, "error unmarshalling TxReadWriteSet")
}

// UnmarshalKVRWSet unmarshals bytes to a KVRWSet
func UnmarshalKVRWSet(bytes []byte) (*kvrwset.KVRWSet, error) {
	rws := &kvrwset.KVRWSet{}
	err := proto.Unmarshal(bytes, rws)
	return rws, errors.Wrap(err, "error unmarshalling KVRWSet")
}

// UnmarshalHashedRWSet unmarshals bytes to a HashedRWSet
func UnmarshalHashedRWSet(bytes []byte) (*kvrwset.HashedRWSet, error) {

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Pass SignedProposal.ProposalPayload exactly, not the whole SignedProposal or its signature
  2. Validate the SignedProposal decodes and its proposal bytes are non-empty before unpacking the payload
  3. Regenerate the proposal with a matching fabric SDK/protos version if bytes came from another component
  4. Sanity-check ChaincodeInvocationSpec fields after unmarshal to catch semantic (not just wire) mismatches

Example fix

// before
cpp, err := protoutil.UnmarshalChaincodeProposalPayload(signedProposalBytes)
// after
cpp, err := protoutil.UnmarshalChaincodeProposalPayload(signedProposal.ProposalPayload)
if err != nil { return fmt.Errorf("invalid proposal payload: %w", err) }
Defensive patterns

Strategy: validation

Validate before calling

func validProposalPayload(sp *pb.SignedProposal) bool {
    return sp != nil && len(sp.ProposalPayload) > 0
}

Type guard

func safeUnmarshalCPP(b []byte) (cpp *peer.ChaincodeProposalPayload, ok bool) {
    cpp, err := protoutil.UnmarshalChaincodeProposalPayload(b)
    return cpp, err == nil && cpp != nil
}

Try / catch

cpp, err := protoutil.UnmarshalChaincodeProposalPayload(signedProp.ProposalPayload)
if err != nil {
    return nil, fmt.Errorf("failed to unmarshal proposal payload: %w", err)
}

Prevention

When it happens

Trigger: Passing a SignedProposal instead of its ProposalPayload field, empty or corrupted proposal bytes, chaincode-side proposals crafted by a malicious/misbehaving client, or proto schema version mismatch.

Common situations: Chaincode handlers unpacking proposals during Invoke, UnpackProposal in SDK/peer code, endorsement validation rejecting client-signed proposals, or CLI tools building transactions with createSignedTxTwoActions.

Related errors


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