hyperledger/fabric · error · VSCCEndorsementPolicyError
collection data should not exist for chaincode %s:%s
Error message
collection data should not exist for chaincode %s:%s
What it means
During a collection-aware deploy validation, VSCC checks whether a collection configuration package for the chaincode already exists in the ledger from a previous definition. If one is found (ccp != nil) while validating what appears to be a fresh deploy of collections, the transaction is rejected as a policy error: collections cannot already be deployed on the chaincode at that point.
Source
Thrown at core/handlers/validation/builtin/v12/validation_logic.go:427
// The following condition check added in v1.1 may not be needed as it is not possible to have the chaincodeName~collection key in
// the lscc namespace before a chaincode deploy. To avoid forks in v1.2, the following condition is retained.
if lsccFunc == lscc.DEPLOY {
colCriteria := privdata.CollectionCriteria{Channel: channelName, Namespace: cdRWSet.Name}
ccp, err := privdata.RetrieveCollectionConfigPackageFromState(colCriteria, state)
if err != nil {
// fail if we get any error other than NoSuchCollectionError
// because it means something went wrong while looking up the
// older collection
if _, ok := err.(privdata.NoSuchCollectionError); !ok {
return &commonerrors.VSCCExecutionFailureError{
Err: fmt.Errorf("unable to check whether collection existed earlier for chaincode %s:%s",
cdRWSet.Name, cdRWSet.Version),
}
}
}
if ccp != nil {
return policyErr(fmt.Errorf("collection data should not exist for chaincode %s:%s", cdRWSet.Name, cdRWSet.Version))
}
}
// TODO: Once the new chaincode lifecycle is available (FAB-8724), the following validation
// and other validation performed in ValidateLSCCInvocation can be moved to LSCC itself.
newCollectionConfigPackage := &pb.CollectionConfigPackage{}
if collectionsConfigArg != nil {
err := proto.Unmarshal(collectionsConfigArg, newCollectionConfigPackage)
if err != nil {
return policyErr(fmt.Errorf("invalid collection configuration supplied for chaincode %s:%s",
cdRWSet.Name, cdRWSet.Version))
}
} else {
return nil
}
if ac.V1_2Validation() {View on GitHub (pinned to 2736b63f8f)
Solutions
- Check whether the chaincode/collections are already deployed (peer chaincode list --collections) and skip re-deploying if so.
- If you intend to change collections on an existing chaincode, use the chaincode upgrade path rather than re-instantiating.
- Make deploy scripts idempotent — query for existing collections before submitting the instantiate transaction.
- Coordinate between operators to avoid duplicate deploy submissions for the same chaincode name/version.
Example fix
// before: unconditional re-instantiate
peer chaincode instantiate -C mychannel -n mycc -v 1.0 -c '{"Args":[]}' --collections-config collections.json
// after: check first
peer chaincode list --collections --channelID mychannel -n mycc || peer chaincode instantiate -C mychannel -n mycc -v 1.0 -c '{"Args":[]}' --collections-config collections.json Defensive patterns
Strategy: validation
Validate before calling
// Before deploying, check whether collections already exist on the chaincode
// peer chaincode list --collections --channelID mychannel -n mycc
// If any collections are returned, use upgrade instead of instantiate.
func shouldDeploy(existingCollectionsJSON []byte) bool {
var ccp map[string]interface{}
if json.Unmarshal(existingCollectionsJSON, &ccp) == nil && len(ccp) > 0 {
return false // collections already deployed — skip deploy
}
return true
} Prevention
- Always run 'peer chaincode list --collections' before an instantiate to confirm no prior config exists
- Make deploy automation idempotent: query-then-deploy rather than blind submit
- Route collection changes on deployed chaincodes through the upgrade path
- Coordinate with other operators or use a deployment lock to avoid duplicate deploys
When it happens
Trigger: Redeploying/instantiating a chaincode whose collection config was already written to the ledger by a previous deploy; submitting a duplicate deploy transaction; attempting to instantiate with collections when the '~collection' keys already exist from an earlier instantiation of the same chaincode name.
Common situations: Re-running an instantiate command that already succeeded (idempotency mistake); upgrading a chaincode and resubmitting collections config when it should be done through the upgrade path; two operators racing to deploy the same chaincode with collections; scripts retrying a deploy whose first attempt actually committed.
Related errors
- invalid key for the collection of chaincode %s:%s; expected
- collection configuration arguments supplied for chaincode %s
- unable to check whether collection existed earlier for chain
- GetChaincodeDeploymentSpec error %s
- VSCC error: invocation of lscc(%s) does not have appropriate
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/5f1d27a5cb73dba6.
Report an issue: GitHub.