{"record":{"id":"dd199629ff612e9e","repo":"hyperledger/fabric","slug":"error-constructing-docker-vm-name-s-breaks-doc","errorCode":null,"errorMessage":"Error constructing Docker VM Name. '%s' breaks Docker's repository naming rules","messagePattern":"Error constructing Docker VM Name\\. '(.+?)' breaks Docker's repository naming rules","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/container/dockercontroller/dockercontroller.go","lineNumber":448,"sourceCode":"\n// GetVMNameForDocker formats the docker image from peer information. This is\n// needed to keep image (repository) names unique in a single host, multi-peer\n// environment (such as a development environment). It computes the hash for the\n// supplied image name and then appends it to the lowercase image name to ensure\n// uniqueness.\nfunc (vm *DockerVM) GetVMNameForDocker(ccid string) (string, error) {\n\tname := vm.preFormatImageName(ccid)\n\t// pre-2.0 used \"-\" as the separator in the ccid, so replace \":\" with\n\t// \"-\" here to ensure 2.0 peers can find pre-2.0 cc images\n\tname = strings.ReplaceAll(name, \":\", \"-\")\n\thash := hex.EncodeToString(util.ComputeSHA256([]byte(name)))\n\tsaniName := vmRegExp.ReplaceAllString(name, \"-\")\n\timageName := strings.ToLower(fmt.Sprintf(\"%s-%s\", saniName, hash))\n\n\t// Check that name complies with Docker's repository naming rules\n\tif !imageRegExp.MatchString(imageName) {\n\t\tdockerLogger.Errorf(\"Error constructing Docker VM Name. '%s' breaks Docker's repository naming rules\", name)\n\t\treturn \"\", fmt.Errorf(\"Error constructing Docker VM Name. '%s' breaks Docker's repository naming rules\", imageName)\n\t}\n\n\treturn imageName, nil\n}\n\nfunc (vm *DockerVM) preFormatImageName(ccid string) string {\n\tname := ccid\n\n\tif vm.NetworkID != \"\" && vm.PeerID != \"\" {\n\t\tname = fmt.Sprintf(\"%s-%s-%s\", vm.NetworkID, vm.PeerID, name)\n\t} else if vm.NetworkID != \"\" {\n\t\tname = fmt.Sprintf(\"%s-%s\", vm.NetworkID, name)\n\t} else if vm.PeerID != \"\" {\n\t\tname = fmt.Sprintf(\"%s-%s\", vm.PeerID, name)\n\t}\n\n\treturn name\n}","sourceCodeStart":430,"sourceCodeEnd":466,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/container/dockercontroller/dockercontroller.go#L430-L466","documentation":"GetVMNameForDocker sanitizes the chaincode VM name (replacing invalid characters with '-'), lowercases it, appends a hash, then validates the result against Docker's image repository name regex. If the composed image name still violates Docker's repository naming rules, this error is returned and no image name is produced. The log message prints the original name while the error prints the sanitized imageName.","triggerScenarios":"GetVMNameForDocker(name) (called by Build, buildImage, Start) when the saniName+hash result fails imageRegExp.MatchString - e.g. name starting or ending with '-'/'.' after sanitization, empty name, or a name longer than 128 chars.","commonSituations":"Chaincode labels or package IDs containing unusual characters that sanitize to leading/trailing separators; extremely long chaincode names; names composed only of characters replaced by '-'.","solutions":["Shorten or rename the chaincode label/package ID so the sanitized name is a valid Docker repo name (alphanumeric, separated by ., _, -, no leading/trailing separators).","Check the imageName printed in the error for illegal characters like leading '-' or '.' introduced by sanitization, and adjust the source name accordingly.","Upgrade Fabric if using an older version - name sanitization rules have been improved over releases."],"exampleFix":"// before\nname := \"-my_chaincode!!\" // sanitizes to \"--my_chaincode--\", invalid repo name\n// after\nname := \"my_chaincode\"","handlingStrategy":"validation","validationCode":"// Go: pre-validate a chaincode name against docker repo rules\nimport \"regexp\"\nvar imageRegExp = regexp.MustCompile(`^[a-z0-9]+((\\.|_|__|-+)[a-z0-9]+)*$`)\nfunc validDockerName(name string) bool { return len(name) <= 128 && imageRegExp.MatchString(name) }","typeGuard":null,"tryCatchPattern":"imageName, err := vm.GetVMNameForDocker(name)\nif err != nil {\n    if strings.Contains(err.Error(), \"breaks Docker's repository naming rules\") {\n        // sanitize/shorten the label before retrying\n    }\n}","preventionTips":["Use lowercase alphanumeric chaincode/package labels with . _ or - separators only.","Keep names short (<100 chars) leaving room for the appended hash.","Avoid names whose sanitized form starts/ends with '-', '.', or '_' (e.g. names of pure symbols).","Test name sanitization in CI before deploying chaincode with unusual labels."],"tags":["docker","naming","validation","image-name"],"backgroundTag":"invalid-docker-repository-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"}