hyperledger/fabric · error · VSCCEndorsementPolicyError

GetChaincodeAction error %s

Error message

GetChaincodeAction error %s

What it means

VSCC unmarshals pRespPayload.Extension into a ChaincodeAction proto. Failure here means the extension bytes are not a valid ChaincodeAction, so the lscc transaction fails validation with this wrapped policy error.

Source

Thrown at core/handlers/validation/builtin/v12/validation_logic.go:571

		// validate chaincode version
		ccVersion := cdsArgs.ChaincodeSpec.ChaincodeId.Version
		// it must comply with the lscc.ChaincodeVersionRegExp
		if !lscc.ChaincodeVersionRegExp.MatchString(ccVersion) {
			return policyErr(errors.Errorf("invalid chaincode version '%s'", ccVersion))
		}

		// get the rwset
		pRespPayload, err := protoutil.UnmarshalProposalResponsePayload(cap.Action.ProposalResponsePayload)
		if err != nil {
			return policyErr(fmt.Errorf("GetProposalResponsePayload error %s", err))
		}
		if pRespPayload.Extension == nil {
			return policyErr(fmt.Errorf("nil pRespPayload.Extension"))
		}
		respPayload, err := protoutil.UnmarshalChaincodeAction(pRespPayload.Extension)
		if err != nil {
			return policyErr(fmt.Errorf("GetChaincodeAction error %s", err))
		}
		txRWSet := &rwsetutil.TxRwSet{}
		if err = txRWSet.FromProtoBytes(respPayload.Results); err != nil {
			return policyErr(fmt.Errorf("txRWSet.FromProtoBytes error %s", err))
		}

		// extract the rwset for lscc
		var lsccrwset *kvrwset.KVRWSet
		for _, ns := range txRWSet.NsRwSets {
			logger.Debugf("Namespace %s", ns.NameSpace)
			if ns.NameSpace == "lscc" {
				lsccrwset = ns.KvRwSet
				break
			}
		}

		// retrieve from the ledger the entry for the chaincode at hand
		cdLedger, ccExistsOnLedger, err := vscc.getInstantiatedCC(chid, cdsArgs.ChaincodeSpec.ChaincodeId.Name)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure the extension is the raw protobuf bytes of the ChaincodeAction returned by the endorser (no re-encoding).
  2. Regenerate the transaction with a matching Fabric SDK version and resubmit.
  3. Diff the proto definitions used by client and peer if a custom build is in play.

Example fix

// before: wrapping the action in another envelope
ext, _ := protoutil.Marshal(&pb.ProposalResponse{Payload: actionBytes})
// after: store the ChaincodeAction bytes directly
ext := actionBytes // protoutil.Marshal(chaincodeAction)
Defensive patterns

Strategy: validation

Validate before calling

var ca pb.ChaincodeAction
if proto.Unmarshal(prp.Extension, &ca) != nil {
    return errors.New("extension is not a valid ChaincodeAction")
}

Type guard

func isChaincodeAction(b []byte) bool {
    var ca pb.ChaincodeAction
    return len(b) > 0 && proto.Unmarshal(b, &ca) == nil
}

Try / catch

if _, err := protoutil.UnmarshalChaincodeAction(prp.Extension); err != nil {
    logger.Warnf("invalid ChaincodeAction in extension: %v", err)
    return policyErr(err)
}

Prevention

When it happens

Trigger: An lscc transaction whose ProposalResponsePayload.Extension bytes are corrupt, truncated, or produced by a different protobuf message type than ChaincodeAction.

Common situations: Mismatched proto definitions between client SDK and peer, custom endorsement code putting the wrong message in the extension, or byte-level corruption/tampering of the transaction.

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/a66ac064d3cfbafc. Report an issue: GitHub.