{"record":{"id":"3ab53b624b84222d","repo":"k3s-io/k3s","slug":"invalid-endpoint-url-s-for-s-v","errorCode":null,"errorMessage":"invalid endpoint URL %s for %s: %v","messagePattern":"invalid endpoint URL (.+?) for (.+?): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/agent/containerd/config.go","lineNumber":275,"sourceCode":"\t// This is the reverse of the DefaultHost normalization\n\tif endpointURL.Host == \"registry-1.docker.io\" {\n\t\tregistry = \"docker.io\"\n\t}\n\n\tswitch endpointURL.Path {\n\tcase \"\", \"/\", \"/v2\":\n\t\t// If the path is empty, /, or /v2, use the default path.\n\t\tendpointURL.Path = \"/v2\"\n\t\treturn registry, endpointURL, false, nil\n\t}\n\n\treturn registry, endpointURL, true, nil\n}\n\nfunc defaultHostConfig(host, mirrorAddr string, config registries.RegistryConfig) (*templates.HostConfig, error) {\n\t_, url, _, err := normalizeEndpointAddress(host, mirrorAddr)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid endpoint URL %s for %s: %v\", host, host, err)\n\t}\n\tif host == \"*\" {\n\t\turl = nil\n\t}\n\treturn &templates.HostConfig{\n\t\tProgram: version.Program,\n\t\tDefault: &templates.RegistryEndpoint{\n\t\t\tURL:    url,\n\t\t\tConfig: config,\n\t\t},\n\t}, nil\n}\n\nfunc configForHost(configs map[string]registries.RegistryConfig, host string) registries.RegistryConfig {\n\t// check for config under modified hostname. If the hostname is unmodified, or there is no config for\n\t// the modified hostname, return the config for the default hostname.\n\tif h, _ := docker.DefaultHost(host); h != host {\n\t\tif c, ok := configs[h]; ok {","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/agent/containerd/config.go#L257-L293","documentation":"defaultHostConfig builds containerd's host configuration for each registry host from registries.yaml and first normalizes the endpoint via normalizeEndpointAddress(host, mirrorAddr). If that returns a parse error, it is wrapped as 'invalid endpoint URL <host> for <host>: <cause>' — both placeholders are the registry host key, and the wrapped cause says exactly what failed to parse.","triggerScenarios":"A registries.yaml entry whose endpoint or mirror address cannot be parsed as a URL: malformed scheme ('http s://x'), stray characters, a broken IPv6 literal ('http://[::1'), or an empty endpoint string.","commonSituations":"Hand-edited /etc/rancher/k3s/registries.yaml; IPv6 mirror addresses missing brackets; URLs pasted with spaces or smart quotes; YAML values mangled by templating.","solutions":["Use fully-qualified endpoints with a scheme: https://mirror.example.com:5000","Quote IPv6 literals correctly: \"http://[2001:db8::1]:5000\"","Lint the registries.yaml before deploying and restart the agent/server after fixing"],"exampleFix":"# before (registries.yaml)\nmirrors:\n  docker.io:\n    endpoint:\n      - \"mirror.example.com:5000\"\n\n# after\nmirrors:\n  docker.io:\n    endpoint:\n      - \"https://mirror.example.com:5000\"","handlingStrategy":"validation","validationCode":"for _, ep := range endpoints {\n    if _, err := url.Parse(strings.TrimSpace(ep)); err != nil {\n        return fmt.Errorf(\"registries.yaml endpoint %q is not a valid URL: %w\", ep, err)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write endpoints with an explicit scheme (https:// or http://)","Bracket IPv6 literals in URLs: http://[2001:db8::1]:5000","Lint registries.yaml in CI before it reaches nodes"],"tags":["registry","containerd","config","url","parsing"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}