hyperledger/fabric · error

chaincode %s exists

Error message

chaincode %s exists

What it means

PutChaincodeToFS refuses to write a chaincode package to the filesystem when a file for the same chaincode name and version already exists at chaincodeInstallPath. It is an idempotency guard: the installed file '<name>.<version>' is the package's on-disk identity, and Hyperledger Fabric does not overwrite an installed chaincode package. The error is raised before os.WriteFile in core/common/ccprovider/cdspackage.go:253.

Source

Thrown at core/common/ccprovider/cdspackage.go:253

	if ccpack.depSpec == nil {
		return errors.New("depspec cannot be nil if buf is not nil")
	}

	if ccpack.data == nil {
		return errors.New("nil data")
	}

	if ccpack.datab == nil {
		return errors.New("nil data bytes")
	}

	ccname := ccpack.depSpec.ChaincodeSpec.ChaincodeId.Name
	ccversion := ccpack.depSpec.ChaincodeSpec.ChaincodeId.Version

	// return error if chaincode exists
	path := fmt.Sprintf("%s/%s.%s", chaincodeInstallPath, ccname, ccversion)
	if _, err := os.Stat(path); err == nil {
		return fmt.Errorf("chaincode %s exists", path)
	}

	if err := os.WriteFile(path, ccpack.buf, 0o644); err != nil {
		return err
	}

	return nil
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Bump ChaincodeId.Version (or use the chaincode upgrade flow with a new version) before installing again.
  2. Check existence first with os.Stat on 'installpath/name.version' and skip the install if a valid package is already present.
  3. Compare the existing file's bytes/hash with the new package; if identical, treat the install as already complete.
  4. Remove the stale package file (or clean the chaincode install directory) only if it is known to be corrupt or unwanted.

Example fix

// before
err := ccprovider.PutChaincode(ctx, cds)
// after
path := filepath.Join(ccprovider.GetChaincodeInstallPath(), name+"."+version)
if _, statErr := os.Stat(path); os.IsNotExist(statErr) {
    err = ccprovider.PutChaincode(ctx, cds)
} else {
    log.Printf("chaincode %s already installed, skipping", path)
}
Defensive patterns

Strategy: validation

Validate before calling

path := filepath.Join(chaincodeInstallPath, ccname+"."+ccversion)
if _, err := os.Stat(path); err == nil {
    return fmt.Errorf("chaincode %s already installed: bump version or skip", path)
}

Try / catch

if err := ccprovider.PutChaincode(ctx, cds); err != nil && strings.HasSuffix(err.Error(), "exists") {
    log.Printf("already installed, skipping: %v", err)
}

Prevention

When it happens

Trigger: Calling PutChaincode (or processCDS) with a ChaincodeDeploymentSpec whose ChaincodeId.Name/ChaincodeId.Version resolve to 'installpath/name.version' that os.Stat finds already on disk; installing the same package twice; a test (TestPutChaincodeToFSErrorPaths) deliberately pre-creating the target file.

Common situations: Re-running a deployment script after a previous install already succeeded; attempting to upgrade chaincode without bumping the version; stale files left in /var/hyperledger/production/chaincodes from a prior environment or failed teardown.

Related errors


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