k3s-io/k3s · error

Initial server URL host is not defined for load balancer

Error message

Initial server URL host is not defined for load balancer

What it means

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.

Source

Thrown at pkg/agent/loadbalancer/utility.go:16

package loadbalancer

import (
	"errors"
	"net/url"
	"slices"
	"strings"
)

func parseURL(serverURL, newHost string) (string, string, error) {
	parsedURL, err := url.Parse(serverURL)
	if err != nil {
		return "", "", err
	}
	if parsedURL.Host == "" {
		return "", "", errors.New("Initial server URL host is not defined for load balancer")
	}
	address := parsedURL.Host
	if parsedURL.Port() == "" {
		if strings.ToLower(parsedURL.Scheme) == "http" {
			address += ":80"
		}
		if strings.ToLower(parsedURL.Scheme) == "https" {
			address += ":443"
		}
	}
	parsedURL.Host = newHost
	return address, parsedURL.String(), nil
}

// sortServers returns a sorted, unique list of strings, with any
// empty values removed. The returned bool is true if the list
// contains the search string.
func sortServers(input []string, search string) ([]string, bool) {

View on GitHub (pinned to 6ba341e396)

Solutions

  1. Set --server to a full URL with host and port: https://<host-or-ip>:6443
  2. Check config.yaml / environment (K3S_URL) quoting and variable expansion so the host portion is not empty
  3. If composing programmatically, validate with url.Parse and require u.Host != "" and u.Port() != "" before passing to the agent

Example fix

# before
K3S_URL=https:// k3s agent ... # host empty -> Initial server URL host is not defined for load balancer

# after
K3S_URL=https://10.0.0.10:6443 k3s agent ...
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(serverURL)
if err != nil { return err }
if u.Host == "" {
    return fmt.Errorf("server URL %q has no host; expected https://<host>:6443", serverURL)
}
if u.Port() == "" { /* parseURL will default 80/443 by scheme */ }

Type guard

func hasHost(serverURL string) bool {
    u, err := url.Parse(serverURL)
    return err == nil && u.Host != ""
}

Prevention

When it happens

Trigger: --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.

Common situations: 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.

Related errors


AI-assisted analysis of k3s-io/k3s@6ba341e396 (2026-08-15). Data as JSON: /api/errors/2395030040e46abc. Report an issue: GitHub.