{"record":{"id":"355b6e2dd689ef59","repo":"containerd/containerd","slug":"invalid-host-name-format","errorCode":null,"errorMessage":"invalid host name format","messagePattern":"invalid host name format","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/remotes/docker/registry.go","lineNumber":242,"sourceCode":"\t}\n\th, p, err := net.SplitHostPort(host)\n\n\t// addrError helps distinguish between errors of form\n\t// \"no colon in address\" and \"too many colons in address\".\n\t// The former is fine as the host string need not have a\n\t// port. Latter needs to be handled.\n\taddrError := &net.AddrError{\n\t\tErr:  \"missing port in address\",\n\t\tAddr: host,\n\t}\n\tif err != nil {\n\t\tif err.Error() != addrError.Error() {\n\t\t\treturn false, err\n\t\t}\n\t\t// host string without any port specified\n\t\th = host\n\t} else if len(p) == 0 {\n\t\treturn false, errors.New(\"invalid host name format\")\n\t}\n\n\t// use ipv4 dotted decimal for further checking\n\tif h == \"localhost\" {\n\t\th = \"127.0.0.1\"\n\t}\n\tip := net.ParseIP(h)\n\n\treturn ip.IsLoopback(), nil\n}\n\nfunc DefaultHTTPTransport(defaultTLSConfig *tls.Config) *http.Transport {\n\treturn &http.Transport{\n\t\tProxy: http.ProxyFromEnvironment,\n\t\tDialContext: (&net.Dialer{\n\t\t\tTimeout:       30 * time.Second,\n\t\t\tKeepAlive:     30 * time.Second,\n\t\t\tFallbackDelay: 300 * time.Millisecond,","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/containerd/containerd/blob/4246446a2bf7d03837b0244118d858799393bd80/core/remotes/docker/registry.go#L224-L260","documentation":"MatchLocalhost checks whether a registry host is a localhost address (to allow skipping TLS, mirroring Docker's registry matching). The host portion must be non-empty after splitting off the port; an empty host (e.g. input like ':5000' or '') yields this error.","triggerScenarios":"Calling MatchLocalhost with a URL/addr whose host part is empty — e.g. an address of form ':5000', a URL missing the host, or a registry endpoint configured with only a port.","commonSituations":"Typo'd registry config in hosts.toml / containerd config (missing hostname); parsing URLs where Host field wasn't populated; programmatic calls passing port-only strings.","solutions":["Fix the registry address to include a hostname (e.g. 'localhost:5000' instead of ':5000')","Validate the endpoint URL before configuring containerd (url.Parse and check u.Host != \"\")","Check hosts.toml / mirror config for missing or empty server hostnames","If parsing user input, reject empty-host URLs at the config-loading boundary"],"exampleFix":"// before\nMatchLocalhost(\":5000\") // invalid host name format\n// after\nu, _ := url.Parse(\"http://localhost:5000\")\nMatchLocalhost(u.Host) // \"localhost:5000\" -> true","handlingStrategy":"validation","validationCode":"u, err := url.Parse(endpoint)\nif err != nil || u.Host == \"\" {\n    return fmt.Errorf(\"registry endpoint must include hostname: %q\", endpoint)\n}","typeGuard":null,"tryCatchPattern":"isLocal, err := registry.MatchLocalhost(addr)\nif err != nil && strings.Contains(err.Error(), \"invalid host name format\") {\n    return fmt.Errorf(\"bad registry address %q: include a hostname\", addr)\n}","preventionTips":["Always configure full host:port for registry endpoints in hosts.toml","Validate endpoint URLs at config load time","Reject port-only or empty hostnames from user input"],"tags":["containerd","registry","validation","localhost"],"backgroundTag":"invalid-hostname-format","analyzedSha":"4246446a2bf7d03837b0244118d858799393bd80","analyzedAt":"2026-09-02T00:14:43.053Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}