hyperledger/fabric · error

Chaincode %s is already instantiated

Error message

Chaincode %s is already instantiated

What it means

For lscc DEPLOY, the validator checks that the target chaincode does not already exist on the ledger (ccExistsOnLedger). If a ChaincodeData entry for the name already exists, a second 'deploy' is rejected — upgrades must use the UPGRADE function instead.

Source

Thrown at core/handlers/validation/builtin/v12/validation_logic.go:639

			return policyErr(fmt.Errorf("expected cc version %s, found %s", cdsArgs.ChaincodeSpec.ChaincodeId.Version, cdRWSet.Version))
		}
		// it must only write to 2 namespaces: LSCC's and the cc that we are deploying/upgrading
		for _, ns := range txRWSet.NsRwSets {
			if ns.NameSpace != "lscc" && ns.NameSpace != cdRWSet.Name && len(ns.KvRwSet.Writes) > 0 {
				return policyErr(fmt.Errorf("LSCC invocation is attempting to write to namespace %s", ns.NameSpace))
			}
		}

		logger.Debugf("Validating %s for cc %s version %s", lsccFunc, cdRWSet.Name, cdRWSet.Version)

		switch lsccFunc {
		case lscc.DEPLOY:

			/******************************************************************/
			/* security check 1 - cc not in the LCCC table of instantiated cc */
			/******************************************************************/
			if ccExistsOnLedger {
				return policyErr(fmt.Errorf("Chaincode %s is already instantiated", cdsArgs.ChaincodeSpec.ChaincodeId.Name))
			}

			/****************************************************************************/
			/* security check 2 - validation of rwset (and of collections if enabled) */
			/****************************************************************************/
			if ac.PrivateChannelData() {
				// do extra validation for collections
				err := vscc.validateRWSetAndCollection(lsccrwset, cdRWSet, lsccArgs, lsccFunc, ac, chid)
				if err != nil {
					return err
				}
			} else {
				// there can only be a single ledger write
				if len(lsccrwset.Writes) != 1 {
					return policyErr(fmt.Errorf("LSCC can only issue a single putState upon deploy"))
				}
			}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Use the upgrade flow (lscc 'upgrade' / SDK upgradeChaincode) to deploy a new version of the existing chaincode.
  2. Choose a unique chaincode name if this is genuinely a new deployment.
  3. Query the ledger (e.g. chaincode list --instantiated) before deploying to check for an existing entry.
  4. Clean up test channels or use distinct names per environment to avoid collisions.

Example fix

// before
client.instantiateChaincode({ chaincodeId: 'mycc', chaincodeVersion: '2.0' })
// after
client.upgradeChaincode({ chaincodeId: 'mycc', chaincodeVersion: '2.0' })
Defensive patterns

Strategy: validation

Validate before calling

// client-side: check before instantiating
resp, _ := admin.QueryInstantiatedChaincodes(channel)
for _, cc := range resp.Chaincodes {
    if cc.Name == chaincodeID {
        return fmt.Errorf("%s already instantiated; use upgrade instead", chaincodeID)
    }
}

Type guard

func alreadyInstantiated(instantiated []*pb.ChaincodeQueryResponse_ChaincodeQueryResponseInfo, name string) bool {
    for _, cc := range instantiated {
        if cc.Name == name { return true }
    }
    return false
}

Try / catch

if err := submitTx(envelope); err != nil {
    if strings.Contains(err.Error(), "is already instantiated") {
        // switch to upgradeChaincode with a new version, or pick a new chaincode name
    }
}

Prevention

When it happens

Trigger: Invoking lscc with function 'deploy' (SDK 'instantiate') for a chaincode name that is already instantiated on the channel, instead of 'upgrade'.

Common situations: Re-running instantiate on an already-deployed chaincode; forgetting to switch the SDK call from instantiateChaincode to upgradeChaincode when adding a new version; duplicate chaincode names across teams on one channel.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/c1fad00e331d8340. Report an issue: GitHub.