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
- Resubmit the transaction collected from healthy endorsers; inspect one reply locally with txRWSet.FromProtoBytes to confirm validity before signing.
- Upgrade peer and SDK to the same Fabric version so rwset proto definitions match.
- 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
- Take Results directly from the ledger simulation (TxRwSet.ToProtoBytes).
- Upgrade peers and SDKs together to avoid rwset proto drift.
- Validate an endorser reply locally before collecting endorsements.
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
- GetChaincodeDeploymentSpec error %s
- GetProposalResponsePayload error %s
- GetChaincodeAction error %s
- invalid key for the collection of chaincode %s:%s; expected
- collection configuration arguments supplied for chaincode %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/899b5bc6c8fa64ec.
Report an issue: GitHub.