hyperledger/fabric · error · VSCCEndorsementPolicyError

GetProposalResponsePayload error %s

Error message

GetProposalResponsePayload error %s

What it means

VSCC attempts to unmarshal cap.Action.ProposalResponsePayload into a ProposalResponsePayload proto. If the bytes are not a valid ProposalResponsePayload, validation fails with this wrapped policy error and the transaction is marked invalid.

Source

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

		if !lscc.ChaincodeNameRegExp.MatchString(ccName) {
			return policyErr(errors.Errorf("invalid chaincode name '%s'", ccName))
		}
		// it can't match the name of one of the system chaincodes
		if _, in := systemChaincodeNames[ccName]; in {
			return policyErr(errors.Errorf("chaincode name '%s' is reserved for system chaincodes", ccName))
		}

		// 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" {

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Rebuild the transaction using the SDK's standard transaction assembly (proposal response payload copied verbatim from the endorser reply).
  2. Check that no intermediate component re-serializes or mutates ProposalResponsePayload bytes.
  3. Align protobuf/Fabric SDK versions between client and peer and resubmit the transaction.

Example fix

// before: re-encoding the payload as JSON
prp, _ := json.Marshal(proposalResponse.Payload)
// after: pass endorser bytes through unchanged
prp := proposalResponse.Payload // raw protobuf bytes from endorser
Defensive patterns

Strategy: validation

Validate before calling

var prp pb.ProposalResponsePayload
if len(cap.Action.ProposalResponsePayload) == 0 || proto.Unmarshal(cap.Action.ProposalResponsePayload, &prp) != nil {
    return errors.New("proposal response payload is not a valid protobuf message")
}

Type guard

func isProposalResponsePayload(b []byte) bool {
    var prp pb.ProposalResponsePayload
    return len(b) > 0 && proto.Unmarshal(b, &prp) == nil
}

Try / catch

prp, err := protoutil.UnmarshalProposalResponsePayload(cap.Action.ProposalResponsePayload)
if err != nil {
    logger.Warnf("corrupt proposal response payload: %v", err)
    return policyErr(err)
}

Prevention

When it happens

Trigger: An endorsed lscc transaction whose ChaincodeEndorsedAction.ProposalResponsePayload bytes are corrupted, truncated, or not a protobuf-encoded ProposalResponsePayload.

Common situations: Custom endorsement-collection code writing the wrong proto message into the payload, SDK/proto incompatibilities, or bytes tampered/reassembled incorrectly by a gateway or intermediary.

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