k3s-io/k3s · error

%s: %s

Error message

%s: %s

What it means

Catch-all for the agent's config download when the HTTP status is anything other than 200 (403 gets the dedicated node-password error above): the error is just '<request-url>: <resp.Status>'. All diagnostics live in the URL and status code, e.g. 'https://10.0.0.1:6443/v1-k3s/configs: 503 Service Unavailable'.

Source

Thrown at pkg/agent/config/config.go:184

		// This allows us to fall back from node identity to token when the node resource is deleted.
		if resp.StatusCode == http.StatusUnauthorized {
			if transport, ok := client.Transport.(*http.Transport); ok && transport.TLSClientConfig != nil && len(transport.TLSClientConfig.Certificates) != 0 {
				logrus.Infof("Node authorization rejected, retrying without client certificate authentication")
				transport.TLSClientConfig.Certificates = []tls.Certificate{}
				resp, err = client.Do(req)
				if err != nil {
					return nil, err
				}
				defer resp.Body.Close()
			}
		}

		if resp.StatusCode == http.StatusForbidden {
			return nil, fmt.Errorf("Node password rejected, duplicate hostname or contents of '%s' may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag", nodePasswordFile)
		}

		if resp.StatusCode != http.StatusOK {
			return nil, fmt.Errorf("%s: %s", u, resp.Status)
		}

		return io.ReadAll(resp.Body)
	}
}

func ensureNodeID(nodeIDFile string) (string, error) {
	if _, err := os.Stat(nodeIDFile); err == nil {
		id, err := os.ReadFile(nodeIDFile)
		return strings.TrimSpace(string(id)), err
	}
	id := make([]byte, 4, 4)
	_, err := cryptorand.Read(id)
	if err != nil {
		return "", err
	}
	nodeID := hex.EncodeToString(id)
	return nodeID, os.WriteFile(nodeIDFile, []byte(nodeID+"\n"), 0644)

View on GitHub (pinned to 6ba341e396)

Solutions

  1. Read the status from the message: 401 -> fix the token/node-password; 503 -> wait and check server health; 404/500 -> inspect server version and logs
  2. Verify reachability: curl -k https://<server>:6443/ping or /readyz
  3. Re-check the --server URL and port
  4. Check server-side logs if the status persists
Defensive patterns

Strategy: try-catch

Try / catch

if err != nil {
    if strings.Contains(err.Error(), ": 503") || strings.Contains(err.Error(), ": 401") {
    // 503: back off and retry (server may still be starting)
    // 401: fix credentials — retrying will not help
    }
}

Prevention

When it happens

Trigger: resp.StatusCode != 200 && != 403 on the config fetch: 401 (invalid node password/token), 503 (server/API server not ready, or the agent's internal load balancer has no healthy backend), 500 (server-side fault), 404 (path/version skew).

Common situations: Agents racing a still-starting server; wrong --server address or port; expired/rotated node token; load balancer pointing at a dead server; apiserver crashlooping.

Related errors


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