{"record":{"id":"677cfad01c88a7e8","repo":"hyperledger/fabric","slug":"upgrading-non-existent-chaincode-s","errorCode":null,"errorMessage":"Upgrading non-existent chaincode %s","messagePattern":"Upgrading non-existent chaincode (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/handlers/validation/builtin/v12/validation_logic.go","lineNumber":680,"sourceCode":"\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\n\t\t\t}\n\n\t\tcase lscc.UPGRADE:\n\t\t\t/**************************************************************/\n\t\t\t/* security check 1 - cc in the LCCC table of instantiated cc */\n\t\t\t/**************************************************************/\n\t\t\tif !ccExistsOnLedger {\n\t\t\t\treturn policyErr(fmt.Errorf(\"Upgrading non-existent chaincode %s\", cdsArgs.ChaincodeSpec.ChaincodeId.Name))\n\t\t\t}\n\n\t\t\t/**********************************************************/\n\t\t\t/* security check 2 - existing cc's version was different */\n\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","sourceCodeStart":662,"sourceCodeEnd":698,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/handlers/validation/builtin/v12/validation_logic.go#L662-L698","documentation":"During LSCC (lifecycle system chaincode) transaction validation, VSCC checks that a chaincode being upgraded via lscc.UPGRADE already exists in the instantiated-chaincode table read from the ledger. If no ChaincodeData exists on the ledger for the target name, the upgrade is rejected as a policy error. This prevents fabricating an 'upgrade' to deploy new chaincode outside normal lifecycle rules.","triggerScenarios":"Submitting an lscc transaction with function UPGRADE for a chaincode name that has never been instantiated (or was fully purged), on channels using the v1.2 validation logic.","commonSituations":"Typing the wrong chaincode name in the upgrade command; upgrading on a different channel than the one where the chaincode was instantiated; attempting an upgrade after the chaincode was deleted or the ledger was resynced/reset.","solutions":["Instantiate the chaincode first (lscc DEPLOY) before attempting an upgrade","Verify the chaincode name matches exactly the one on the ledger (peer chaincode list --installed/instantiated)","Confirm you are issuing the upgrade on the correct channel where the chaincode is instantiated"],"exampleFix":"// before\npeer chaincode upgrade -C mychannel -n wrongname -v 2.0 ...\n// after\npeer chaincode list -C mychannel   # confirm exact name\npeer chaincode upgrade -C mychannel -n mycc -v 2.0 ...","handlingStrategy":"validation","validationCode":"const instantiated = await peer.chaincodeList(channelName);\nif (!instantiated.some(cc => cc.name === targetName)) {\n  throw new Error(`Chaincode ${targetName} is not instantiated; instantiate before upgrade`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await contract.submitTransaction('upgrade', ...);\n} catch (e) {\n  if (String(e).includes('Upgrading non-existent chaincode')) {\n    // fall back to instantiate flow\n  }\n}","preventionTips":["Always run peer chaincode list -C <channel> before upgrading","Keep chaincode names in config files to avoid typos","Script deploy+upgrade as paired operations on the same channel"],"tags":["hyperledger-fabric","chaincode-lifecycle","vscc","lscc"],"backgroundTag":"chaincode-upgrade-nonexistent","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"}