hyperledger/fabric · error · VSCCEndorsementPolicyError

txRWSet.FromProtoBytes error %s

Error message

txRWSet.FromProtoBytes error %s

What it means

VSCC converts respPayload.Results into a rwsetutil.TxRwSet via FromProtoBytes. This fails when the results bytes are not a valid TxReadWriteSet proto, meaning the endorsed write set is corrupt or of the wrong shape; the transaction is rejected with this policy error.

Source

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

		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)
		if err != nil {
			return &commonerrors.VSCCExecutionFailureError{Err: err}
		}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Resubmit the transaction collected from healthy endorsers; inspect one reply locally with txRWSet.FromProtoBytes to confirm validity before signing.
  2. Upgrade peer and SDK to the same Fabric version so rwset proto definitions match.
  3. If running custom/modified endorser code, ensure Results is the marshaled TxReadWriteSet produced by the standard ledger simulation.

Example fix

// before: manually stuffing kvrwset bytes into Results
results, _ := proto.Marshal(&kvrwset.KVRWSet{})
// after: use the simulated TxReadWriteSet
results, _ := txRWSet.ToProtoBytes() // rwsetutil.TxRwSet
Defensive patterns

Strategy: validation

Validate before calling

txRWSet := &rwsetutil.TxRwSet{}
if err := txRWSet.FromProtoBytes(ca.Results); err != nil {
    return fmt.Errorf("endorsed results are not a valid rwset: %v", err)
}

Type guard

func isValidRwsetBytes(b []byte) bool {
    txRWSet := &rwsetutil.TxRwSet{}
    return txRWSet.FromProtoBytes(b) == nil
}

Try / catch

if err := txRWSet.FromProtoBytes(respPayload.Results); err != nil {
    logger.Warnf("rwset decode failed (proto drift or corruption): %v", err)
    return policyErr(err)
}

Prevention

When it happens

Trigger: An lscc transaction whose ChaincodeAction.Results bytes fail to decode into a valid transaction read/write set (empty, truncated, or incompatible kvrwset encoding).

Common situations: Peer/SDK proto drift (especially after Fabric version upgrades changing rwset messages), custom endorser code emitting malformed Results, or corrupted transactions from unreliable transports.

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