{"record":{"id":"2395030040e46abc","repo":"k3s-io/k3s","slug":"initial-server-url-host-is-not-defined-for-load-ba","errorCode":null,"errorMessage":"Initial server URL host is not defined for load balancer","messagePattern":"Initial server URL host is not defined for load balancer","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/agent/loadbalancer/utility.go","lineNumber":16,"sourceCode":"package loadbalancer\n\nimport (\n\t\"errors\"\n\t\"net/url\"\n\t\"slices\"\n\t\"strings\"\n)\n\nfunc parseURL(serverURL, newHost string) (string, string, error) {\n\tparsedURL, err := url.Parse(serverURL)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tif parsedURL.Host == \"\" {\n\t\treturn \"\", \"\", errors.New(\"Initial server URL host is not defined for load balancer\")\n\t}\n\taddress := parsedURL.Host\n\tif parsedURL.Port() == \"\" {\n\t\tif strings.ToLower(parsedURL.Scheme) == \"http\" {\n\t\t\taddress += \":80\"\n\t\t}\n\t\tif strings.ToLower(parsedURL.Scheme) == \"https\" {\n\t\t\taddress += \":443\"\n\t\t}\n\t}\n\tparsedURL.Host = newHost\n\treturn address, parsedURL.String(), nil\n}\n\n// sortServers returns a sorted, unique list of strings, with any\n// empty values removed. The returned bool is true if the list\n// contains the search string.\nfunc sortServers(input []string, search string) ([]string, bool) {","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/agent/loadbalancer/utility.go#L1-L34","documentation":"parseURL takes the configured server URL and a replacement host (the load-balancer address). After url.Parse succeeds it requires a non-empty URL.Host; an empty host means the URL lacks authority (hostname/port), e.g. only a scheme or path was supplied. The LB needs the original host:port to build its upstream server list, so it fails immediately.","triggerScenarios":"--server set to a URL without a host: 'https://', 'tcp://', '/127.0.0.1:6443', or a bare string that parses host-less; programmatic callers passing url.String() of a parsed relative URL.","commonSituations":"Config.yaml templating that renders an empty server host; YAML quoting mistakes producing scheme-only values; scripts composing the server URL from an unset environment variable.","solutions":["Set --server to a full URL with host and port: https://<host-or-ip>:6443","Check config.yaml / environment (K3S_URL) quoting and variable expansion so the host portion is not empty","If composing programmatically, validate with url.Parse and require u.Host != \"\" and u.Port() != \"\" before passing to the agent"],"exampleFix":"# before\nK3S_URL=https:// k3s agent ... # host empty -> Initial server URL host is not defined for load balancer\n\n# after\nK3S_URL=https://10.0.0.10:6443 k3s agent ...","handlingStrategy":"validation","validationCode":"u, err := url.Parse(serverURL)\nif err != nil { return err }\nif u.Host == \"\" {\n    return fmt.Errorf(\"server URL %q has no host; expected https://<host>:6443\", serverURL)\n}\nif u.Port() == \"\" { /* parseURL will default 80/443 by scheme */ }","typeGuard":"func hasHost(serverURL string) bool {\n    u, err := url.Parse(serverURL)\n    return err == nil && u.Host != \"\"\n}","tryCatchPattern":null,"preventionTips":["Template config.yaml with defaults so server is never rendered empty","Validate K3S_URL/--server with url.Parse + Host check in bootstrap scripts","Prefer fully-qualified host:port URLs for agents"],"tags":["load-balancer","url","config","validation"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}