hyperledger/fabric · error · VSCCEndorsementPolicyError

No read write set for lscc was found

Error message

No read write set for lscc was found

What it means

During V1.2 endorsement validation, ValidateLSCCInvocation checks that a deploy/upgrade transaction actually contains a read-write set for the lifecycle system chaincode (lscc). If the lscc namespace rwset is entirely absent (nil), the transaction is rejected as a policy error. This guards against transactions claiming to deploy a chaincode without the corresponding ledger update lscc performs.

Source

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

			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}
		}

		/******************************************/
		/* security check 0 - validation of rwset */
		/******************************************/
		// there has to be a write-set
		if lsccrwset == nil {
			return policyErr(fmt.Errorf("No read write set for lscc was found"))
		}
		// there must be at least one write
		if len(lsccrwset.Writes) < 1 {
			return policyErr(fmt.Errorf("LSCC must issue at least one single putState upon deploy/upgrade"))
		}
		// the first key name must be the chaincode id provided in the deployment spec
		if lsccrwset.Writes[0].Key != cdsArgs.ChaincodeSpec.ChaincodeId.Name {
			return policyErr(fmt.Errorf("expected key %s, found %s", cdsArgs.ChaincodeSpec.ChaincodeId.Name, lsccrwset.Writes[0].Key))
		}
		// the value must be a ChaincodeData struct
		cdRWSet := &ccprovider.ChaincodeData{}
		err = proto.Unmarshal(lsccrwset.Writes[0].Value, cdRWSet)
		if err != nil {
			return policyErr(fmt.Errorf("unmarshalling of ChaincodeData failed, error %s", err))
		}
		// the chaincode name in the lsccwriteset must match the chaincode name in the deployment spec
		if cdRWSet.Name != cdsArgs.ChaincodeSpec.ChaincodeId.Name {
			return policyErr(fmt.Errorf("expected cc name %s, found %s", cdsArgs.ChaincodeSpec.ChaincodeId.Name, cdRWSet.Name))

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure the transaction is produced by the normal SDK/lscc flow so lscc's putState generates a proper lscc rwset entry.
  2. Verify all peers and chaincode use matching Fabric versions so endorsement generates the expected lscc writes.
  3. Rebuild and resubmit the deploy/upgrade transaction using a current fabric-sdk-node/java/go release.
  4. Inspect the submitted envelope's TxRWSet (decode with peer or fabric-tools) to confirm the lscc namespace write exists before resubmitting.

Example fix

// before: crafting a proposal that skips lscc writes
invoke('lscc', 'deploy', args) // rwset missing
// after: use the standard lifecycle call so lscc issues its putState
client.installChaincode(...) ; client.instantiateChaincode({ chaincodeId, fcn: 'init' })
Defensive patterns

Strategy: validation

Validate before calling

// Go (peer-side concept): decode the envelope's TxRWSet and check before relying on lscc validation
rwSet, err := rwset.TxRwSetFromProtoBytes(txPayloadData)
if err != nil { return err }
if rwSet.GetNsRwSet("lscc") == nil {
    return fmt.Errorf("transaction lacks lscc rwset; resubmit via standard instantiate flow")
}

Type guard

func hasLsccRwSet(txRWSet *rwset.TxRwSet) bool {
    return txRWSet != nil && txRWSet.GetNsRwSet("lscc") != nil
}

Try / catch

if err := submitTx(envelope); err != nil {
    if strings.Contains(err.Error(), "No read write set for lscc was found") {
        // rebuild the instantiate/upgrade proposal with a current SDK and re-endorse
    }
}

Prevention

When it happens

Trigger: A transaction invokes lscc (deploy/upgrade) but the transaction's rwset contains no namespace rw-set for "lscc" at all, so the validator's txRWSet.GetNsRwSet("lscc") returns nil and it is passed as lsccrwset.

Common situations: Malformed or hand-crafted transactions submitted directly to orderer; endorsing peers running incompatible chaincode/validation code versions; rwset discarded or truncated by a broken endorsement pipeline; replaying a transaction that lost its lscc writes.

Related errors


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