{"record":{"id":"a91cf0e86ac75a25","repo":"hyperledger/fabric","slug":"lscc-can-only-issue-a-single-putstate-upon-upgrade","errorCode":null,"errorMessage":"LSCC can only issue a single putState upon upgrade","messagePattern":"LSCC can only issue a single putState upon upgrade","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/handlers/validation/builtin/v12/validation_logic.go","lineNumber":703,"sourceCode":"\t\t\t/**********************************************************/\n\t\t\tif cdLedger.Version == cdsArgs.ChaincodeSpec.ChaincodeId.Version {\n\t\t\t\treturn policyErr(fmt.Errorf(\"Existing version of the cc on the ledger (%s) should be different from the upgraded one\", cdsArgs.ChaincodeSpec.ChaincodeId.Version))\n\t\t\t}\n\n\t\t\t/****************************************************************************/\n\t\t\t/* security check 3 validation of rwset (and of collections if enabled) */\n\t\t\t/****************************************************************************/\n\t\t\t// Only in v1.2, a collection can be updated during a chaincode upgrade\n\t\t\tif ac.V1_2Validation() {\n\t\t\t\t// do extra validation for collections\n\t\t\t\terr := vscc.validateRWSetAndCollection(lsccrwset, cdRWSet, lsccArgs, lsccFunc, ac, chid)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// there can only be a single ledger write\n\t\t\t\tif len(lsccrwset.Writes) != 1 {\n\t\t\t\t\treturn policyErr(fmt.Errorf(\"LSCC can only issue a single putState upon upgrade\"))\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/*****************************************************/\n\t\t\t/* security check 4 - check the instantiation policy */\n\t\t\t/*****************************************************/\n\t\t\tpol := cdLedger.InstantiationPolicy\n\t\t\tif pol == nil {\n\t\t\t\treturn policyErr(fmt.Errorf(\"No instantiation policy was specified\"))\n\t\t\t}\n\t\t\t// FIXME: could we actually pull the cds package from the\n\t\t\t// file system to verify whether the policy that is specified\n\t\t\t// here is the same as the one on disk?\n\t\t\t// PROS: we prevent attacks where the policy is replaced\n\t\t\t// CONS: this would be a point of non-determinism\n\t\t\terr := vscc.checkInstantiationPolicy(chid, env, pol, payl)\n\t\t\tif err != nil {\n\t\t\t\treturn err","sourceCodeStart":685,"sourceCodeEnd":721,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/handlers/validation/builtin/v12/validation_logic.go#L685-L721","documentation":"For an UPGRADE, LSCC's read-write set must contain exactly one write (the single putState updating the chaincode data on the ledger). VSCC rejects the transaction if the LSCC rwset contains zero or multiple writes, since anything else would indicate a tampered or malformed transaction.","triggerScenarios":"An lscc UPGRADE transaction whose lsccrwset.Writes has a length != 1 (no writes, or multiple writes), evaluated under v1.2 validation.","commonSituations":"A tampered or hand-crafted transaction proposal; a modified/corrupted LSCC implementation; malicious endorsement attempting to sneak extra writes into the upgrade.","solutions":["Use the stock LSCC from the matching Fabric release to generate transactions","Rebuild the proposal with the SDK/CLI so exactly one putState is produced for the upgrade","If seen unexpectedly, investigate whether a peer or endorser binary is modified/misbehaving"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await submitLifecycleTx('upgrade');\n} catch (e) {\n  if (String(e).includes('single putState upon upgrade')) {\n    // treat as tampered/non-standard tx; rebuild with stock LSCC/SDK\n  }\n}","preventionTips":["Use stock LSCC and official SDKs to build lifecycle transactions","Never hand-craft lscc proposal payloads","Keep peer binaries unmodified and verified"],"tags":["hyperledger-fabric","vscc","rwset","lscc"],"backgroundTag":"invalid-transaction-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"}