{"record":{"id":"1be488580e1fd2fc","repo":"hyperledger/fabric","slug":"lscc-can-only-issue-one-or-two-putstate-upon-deplo-1be488","errorCode":null,"errorMessage":"LSCC can only issue one or two putState upon deploy","messagePattern":"LSCC can only issue one or two putState upon deploy","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/handlers/validation/builtin/v13/lscc_validation_logic.go","lineNumber":232,"sourceCode":"}\n\n// validateRWSetAndCollection performs validation of the rwset\n// of an LSCC deploy operation and then it validates any collection\n// configuration\nfunc (vscc *Validator) validateRWSetAndCollection(\n\tlsccrwset *kvrwset.KVRWSet,\n\tcdRWSet *ccprovider.ChaincodeData,\n\tlsccArgs [][]byte,\n\tlsccFunc string,\n\tac vc.Capabilities,\n\tchannelName string,\n) commonerrors.TxValidationError {\n\t/********************************************/\n\t/* security check 0.a - validation of rwset */\n\t/********************************************/\n\t// there can only be one or two writes\n\tif len(lsccrwset.Writes) > 2 {\n\t\treturn policyErr(fmt.Errorf(\"LSCC can only issue one or two putState upon deploy\"))\n\t}\n\n\t/**********************************************************/\n\t/* security check 0.b - validation of the collection data */\n\t/**********************************************************/\n\tvar collectionsConfigArg []byte\n\tif len(lsccArgs) > 5 {\n\t\tcollectionsConfigArg = lsccArgs[5]\n\t}\n\n\tvar collectionsConfigLedger []byte\n\tif len(lsccrwset.Writes) == 2 {\n\t\tkey := privdata.BuildCollectionKVSKey(cdRWSet.Name)\n\t\tif lsccrwset.Writes[1].Key != key {\n\t\t\treturn policyErr(fmt.Errorf(\"invalid key for the collection of chaincode %s:%s; expected '%s', received '%s'\",\n\t\t\t\tcdRWSet.Name, cdRWSet.Version, key, lsccrwset.Writes[1].Key))\n\t\t}\n","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/handlers/validation/builtin/v13/lscc_validation_logic.go#L214-L250","documentation":"Upon deploy, LSCC's transaction write set may contain at most two putState writes: the chaincode data and (optionally) the collection config. validateRWSetAndCollection rejects the transaction with this policy error if the LSCC read-write set contains more than two writes, since additional writes indicate a malformed or malicious deploy invocation.","triggerScenarios":"A chaincode deploy/upgrade invocation whose LSCC rwset has len(Writes) > 2 — e.g. a crafted proposal writing extra keys through lscc, or tooling that packs additional state mutations into the LSCC transaction.","commonSituations":"Custom or patched lifecycle tooling injecting extra writes into the LSCC transaction; fabric version mismatch where a peer receives deploy-format transactions it doesn't expect (pre-v2 vs v2 lifecycle); malicious proposals probing the validator.","solutions":["Use the standard fabric SDK/CLI to deploy or upgrade chaincode so the LSCC rwset contains only the permitted writes","Do not add extra putState writes to LSCC transactions; chaincode state writes belong to user chaincode, not the lifecycle call","Ensure all peers and clients run a consistent fabric version so the correct lifecycle path (v1 lscc deploy vs v2 _lifecycle) is used"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// client-side: do not extend LSCC transactions with extra writes\n// use only the official lifecycle APIs (lscc deploy/upgrade or _lifecycle)\nif (!usingOfficialLifecycleApi) {\n  throw new Error('custom LSCC transaction construction detected; use standard lifecycle APIs');\n}","typeGuard":"function isStandardLifecycleInvocation(tx) {\n  return tx.chaincodeId === 'lscc' || tx.chaincodeId === '_lifecycle';\n}","tryCatchPattern":"try {\n  await contract.submitTransaction('DeployChaincode', ...args);\n} catch (err) {\n  if (String(err).includes('LSCC can only issue one or two putState')) {\n    // rebuild the deploy transaction with only the standard LSCC writes\n  }\n  throw err;\n}","preventionTips":["Never hand-craft LSCC read-write sets; use the fabric SDK/CLI lifecycle commands","Ensure fabric versions are consistent across the network so the right lifecycle path is exercised","Treat extra writes in lifecycle transactions as a red flag for malicious or buggy tooling"],"tags":["hyperledger-fabric","lscc","rwset","validation"],"backgroundTag":"invalid-lscc-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"}