{"record":{"id":"15391daa708300a0","repo":"hyperledger/fabric","slug":"no-read-write-set-for-lscc-was-found","errorCode":null,"errorMessage":"No read write set for lscc was found","messagePattern":"No read write set for lscc was found","errorType":"validation","errorClass":"VSCCEndorsementPolicyError","httpStatus":null,"severity":"error","filePath":"core/handlers/validation/builtin/v12/validation_logic.go","lineNumber":599,"sourceCode":"\t\t\tlogger.Debugf(\"Namespace %s\", ns.NameSpace)\n\t\t\tif ns.NameSpace == \"lscc\" {\n\t\t\t\tlsccrwset = ns.KvRwSet\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// retrieve from the ledger the entry for the chaincode at hand\n\t\tcdLedger, ccExistsOnLedger, err := vscc.getInstantiatedCC(chid, cdsArgs.ChaincodeSpec.ChaincodeId.Name)\n\t\tif err != nil {\n\t\t\treturn &commonerrors.VSCCExecutionFailureError{Err: err}\n\t\t}\n\n\t\t/******************************************/\n\t\t/* security check 0 - validation of rwset */\n\t\t/******************************************/\n\t\t// there has to be a write-set\n\t\tif lsccrwset == nil {\n\t\t\treturn policyErr(fmt.Errorf(\"No read write set for lscc was found\"))\n\t\t}\n\t\t// there must be at least one write\n\t\tif len(lsccrwset.Writes) < 1 {\n\t\t\treturn policyErr(fmt.Errorf(\"LSCC must issue at least one single putState upon deploy/upgrade\"))\n\t\t}\n\t\t// the first key name must be the chaincode id provided in the deployment spec\n\t\tif lsccrwset.Writes[0].Key != cdsArgs.ChaincodeSpec.ChaincodeId.Name {\n\t\t\treturn policyErr(fmt.Errorf(\"expected key %s, found %s\", cdsArgs.ChaincodeSpec.ChaincodeId.Name, lsccrwset.Writes[0].Key))\n\t\t}\n\t\t// the value must be a ChaincodeData struct\n\t\tcdRWSet := &ccprovider.ChaincodeData{}\n\t\terr = proto.Unmarshal(lsccrwset.Writes[0].Value, cdRWSet)\n\t\tif err != nil {\n\t\t\treturn policyErr(fmt.Errorf(\"unmarshalling of ChaincodeData failed, error %s\", err))\n\t\t}\n\t\t// the chaincode name in the lsccwriteset must match the chaincode name in the deployment spec\n\t\tif cdRWSet.Name != cdsArgs.ChaincodeSpec.ChaincodeId.Name {\n\t\t\treturn policyErr(fmt.Errorf(\"expected cc name %s, found %s\", cdsArgs.ChaincodeSpec.ChaincodeId.Name, cdRWSet.Name))","sourceCodeStart":581,"sourceCodeEnd":617,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/handlers/validation/builtin/v12/validation_logic.go#L581-L617","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the transaction is produced by the normal SDK/lscc flow so lscc's putState generates a proper lscc rwset entry.","Verify all peers and chaincode use matching Fabric versions so endorsement generates the expected lscc writes.","Rebuild and resubmit the deploy/upgrade transaction using a current fabric-sdk-node/java/go release.","Inspect the submitted envelope's TxRWSet (decode with peer or fabric-tools) to confirm the lscc namespace write exists before resubmitting."],"exampleFix":"// before: crafting a proposal that skips lscc writes\ninvoke('lscc', 'deploy', args) // rwset missing\n// after: use the standard lifecycle call so lscc issues its putState\nclient.installChaincode(...) ; client.instantiateChaincode({ chaincodeId, fcn: 'init' })","handlingStrategy":"validation","validationCode":"// Go (peer-side concept): decode the envelope's TxRWSet and check before relying on lscc validation\nrwSet, err := rwset.TxRwSetFromProtoBytes(txPayloadData)\nif err != nil { return err }\nif rwSet.GetNsRwSet(\"lscc\") == nil {\n    return fmt.Errorf(\"transaction lacks lscc rwset; resubmit via standard instantiate flow\")\n}","typeGuard":"func hasLsccRwSet(txRWSet *rwset.TxRwSet) bool {\n    return txRWSet != nil && txRWSet.GetNsRwSet(\"lscc\") != nil\n}","tryCatchPattern":"if err := submitTx(envelope); err != nil {\n    if strings.Contains(err.Error(), \"No read write set for lscc was found\") {\n        // rebuild the instantiate/upgrade proposal with a current SDK and re-endorse\n    }\n}","preventionTips":["Always instantiate/upgrade via SDK lifecycle APIs, never hand-crafted envelopes","Keep peer and SDK versions aligned","Decode and inspect the rwset before submitting deploy transactions"],"tags":["hyperledger-fabric","lscc","rwset","transaction-validation"],"backgroundTag":"missing-rwset","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}