{"record":{"id":"623b71aeb701ee3f","repo":"hyperledger/fabric","slug":"lscc-must-issue-at-least-one-single-putstate-upon","errorCode":null,"errorMessage":"LSCC must issue at least one single putState upon deploy/upgrade","messagePattern":"LSCC must issue at least one single putState upon deploy/upgrade","errorType":"validation","errorClass":"VSCCEndorsementPolicyError","httpStatus":null,"severity":"error","filePath":"core/handlers/validation/builtin/v12/validation_logic.go","lineNumber":603,"sourceCode":"\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))\n\t\t}\n\t\t// the chaincode version in the lsccwriteset must match the chaincode version in the deployment spec\n\t\tif cdRWSet.Version != cdsArgs.ChaincodeSpec.ChaincodeId.Version {\n\t\t\treturn policyErr(fmt.Errorf(\"expected cc version %s, found %s\", cdsArgs.ChaincodeSpec.ChaincodeId.Version, cdRWSet.Version))","sourceCodeStart":585,"sourceCodeEnd":621,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/handlers/validation/builtin/v12/validation_logic.go#L585-L621","documentation":"A deploy/upgrade of a chaincode must cause lscc to write at least one key to the ledger (the ChaincodeData record). If the lscc rwset exists but has zero writes, the validator rejects the transaction because no chaincode registration actually occurred.","triggerScenarios":"Invoking lscc deploy/upgrade where lscc returns without calling putState, e.g. lscc code path short-circuits, or the rwset contains only reads for lscc.","commonSituations":"Custom-patched lscc; chaincode instantiated via deprecated/manual flows; rwset generated by a simulation that skipped lscc writes; version skew between peer validation code (v12) and lscc behavior.","solutions":["Re-run instantiation through the official SDK/lifecycle so lscc issues its putState of ChaincodeData.","Check lscc is unmodified (stock system chaincode) on all peers.","Align peer binary and validation plugin versions (v12 validator expects lscc write semantics).","Decode the transaction rwset to confirm lscc has >=1 write before resubmitting."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"ns := rwSet.GetNsRwSet(\"lscc\")\nif ns == nil || len(ns.KvRwSet.Writes) < 1 {\n    return fmt.Errorf(\"lscc must write ChaincodeData; regenerate the deploy transaction\")\n}","typeGuard":"func lsccHasWrites(txRWSet *rwset.TxRwSet) bool {\n    ns := txRWSet.GetNsRwSet(\"lscc\")\n    return ns != nil && len(ns.KvRwSet.Writes) >= 1\n}","tryCatchPattern":"if err := submitTx(envelope); err != nil {\n    if strings.Contains(err.Error(), \"must issue at least one single putState\") {\n        // re-run instantiate via official SDK / stock lscc\n    }\n}","preventionTips":["Use unmodified stock lscc","Avoid custom lscc patches that skip putState","Keep Fabric peer versions uniform across the network"],"tags":["hyperledger-fabric","lscc","rwset","putstate"],"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"}