{"record":{"id":"26ebffe41ee25f6c","repo":"hyperledger/fabric","slug":"chaincode-name-s-is-the-name-of-a-system-chainc","errorCode":null,"errorMessage":"chaincode name '%s' is the name of a system chaincode","messagePattern":"chaincode name '(.+?)' is the name of a system chaincode","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/lifecycle/scc.go","lineNumber":730,"sourceCode":"\tcollectionNameRegExp = regexp.MustCompile(\"^[A-Za-z0-9-]+([A-Za-z0-9_-]+)*$\")\n\n\t// currently defined system chaincode names that shouldn't\n\t// be allowed as user-defined chaincode names\n\tsystemChaincodeNames = map[string]struct{}{\n\t\t\"cscc\": {},\n\t\t\"escc\": {},\n\t\t\"lscc\": {},\n\t\t\"qscc\": {},\n\t\t\"vscc\": {},\n\t}\n)\n\nfunc (i *Invocation) validateInput(name, version string, collections *pb.CollectionConfigPackage) error {\n\tif !ChaincodeNameRegExp.MatchString(name) {\n\t\treturn errors.Errorf(\"invalid chaincode name '%s'. Names can only consist of alphanumerics, '_', and '-' and can only begin with alphanumerics\", name)\n\t}\n\tif _, ok := systemChaincodeNames[name]; ok {\n\t\treturn errors.Errorf(\"chaincode name '%s' is the name of a system chaincode\", name)\n\t}\n\n\tif !ChaincodeVersionRegExp.MatchString(version) {\n\t\treturn errors.Errorf(\"invalid chaincode version '%s'. Versions can only consist of alphanumerics, '_', '-', '+', and '.'\", version)\n\t}\n\n\tcollConfigs, err := extractStaticCollectionConfigs(collections)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// we extract the channel config to check whether the supplied collection configuration\n\t// complies to the given msp configuration and performs semantic validation.\n\t// Channel config may change afterwards (i.e., after endorsement or commit of this transaction).\n\t// Fabric will deal with the situation where some collection configs are no longer meaningful.\n\t// Therefore, the use of channel config for verifying during endorsement is more\n\t// towards catching manual errors in the config as oppose to any attempt of serializability.\n\tchannelConfig := i.SCC.ChannelConfigSource.GetStableChannelConfig(i.ChannelID)\n\tif channelConfig == nil {","sourceCodeStart":712,"sourceCodeEnd":748,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/lifecycle/scc.go#L712-L748","documentation":"validateInput rejects chaincode names that collide with system chaincode names (such as _lifecycle, cscc, qscc, escc, vscc) to prevent shadowing or confusing built-in SCCs. This is a reserved-name guard, not a format error.","triggerScenarios":"Approving or committing a user chaincode whose name matches an entry in the systemChaincodeNames map (e.g. '_lifecycle').","commonSituations":"Developers experimenting with lifecycle internals naming their chaincode '_lifecycle' or 'qscc', or test fixtures reusing SCC names.","solutions":["Choose a user chaincode name that does not collide with any system chaincode name","If testing lifecycle itself, use a prefixed name like 'test-lifecycle-cc'"],"exampleFix":"// before\nname := \"_lifecycle\"\n// after\nname := \"my_lifecycle_cc\"","handlingStrategy":"validation","validationCode":"// Go\nvar reserved = map[string]bool{\"cscc\":true,\"qscc\":true,\"escc\":true,\"vscc\":true,\"_lifecycle\":true}\nfunc isReservedName(name string) bool { return reserved[name] }","typeGuard":null,"tryCatchPattern":"if isReservedName(name) { return fmt.Errorf(\"name %q is reserved\", name) }\n// then invoke lifecycle APIs","preventionTips":["Maintain a reserved-name list in tooling that fails fast","Prefix test chaincodes to avoid SCC name collisions","Review naming before adding new system chaincodes"],"tags":["hyperledger-fabric","validation","naming"],"backgroundTag":"reserved-chaincode-name","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"}