hyperledger/fabric · error

error unmarshalling ChaincodeAction

Error message

error unmarshalling ChaincodeAction

What it means

Returned by protoutil.UnmarshalChaincodeAction when proto.Unmarshal fails to decode bytes into a peer.ChaincodeAction. The wrap adds message-type context to the underlying protobuf error. It means the action bytes (typically ProposalResponsePayload.Extension or the transaction action's results) are invalid or of the wrong type.

Solutions

  1. Verify you pass the correct field (ChaincodeAction lives in ProposalResponsePayload.Extension / Action.Results), not the parent payload bytes.
  2. Check for empty/truncated results before unmarshaling and fail fast with context.
  3. Ensure the transaction was produced by a Fabric version compatible with your parser.
  4. Validate the parent structures first (Envelope -> Payload -> Transaction -> Action) to ensure field offsets are right.
  5. Log length and base64 of failing bytes to diagnose corruption.

Example fix

// before
action, _ := protoutil.UnmarshalChaincodeAction(prpBytes) // parent payload, wrong bytes
// after
prp, _ := protoutil.UnmarshalProposalResponsePayload(prpBytes)
action, err := protoutil.UnmarshalChaincodeAction(prp.Extension)
if err != nil {
    return fmt.Errorf("bad chaincode action: %w", err)
}
Defensive patterns

Strategy: validation

Validate before calling

func validChaincodeAction(prp *peer.ProposalResponsePayload) bool {
    return prp != nil && len(prp.Extension) > 0
}

Type guard

func isChaincodeAction(v any) bool {
    _, ok := v.(*peer.ChaincodeAction)
    return ok
}

Try / catch

action, err := protoutil.UnmarshalChaincodeAction(prp.Extension)
if err != nil {
    return fmt.Errorf("cannot extract chaincode action: %w", err)
}

Prevention

When it happens

Trigger: Calling UnmarshalChaincodeAction on results fields that are empty, truncated, or actually another message type; reached from transaction validation (extractDependenciesForTx, ValidateLSCCInvocation), read-write set extraction, and CLI invoke/query flows.

Common situations: Parsing committed transactions from blocks where the action payload was produced by a different Fabric version; extracting rwset bytes from the wrong field; corrupted transaction records.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


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

Appendix: source

Thrown at protoutil/unmarshalers.go:123

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

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

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

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

// UnmarshalChaincodeEvents unmarshals bytes to a ChaincodeEvent
func UnmarshalChaincodeEvents(eBytes []byte) (*peer.ChaincodeEvent, error) {
	chaincodeEvent := &peer.ChaincodeEvent{}
	err := proto.Unmarshal(eBytes, chaincodeEvent)
	return chaincodeEvent, errors.Wrap(err, "error unmarshalling ChaicnodeEvent")
}

// UnmarshalProposalResponsePayload unmarshals bytes to a ProposalResponsePayload
func UnmarshalProposalResponsePayload(prpBytes []byte) (*peer.ProposalResponsePayload, error) {

View on GitHub (pinned to 2736b63f8f)