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
- 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
- Verify reachability: curl -k https://<server>:6443/ping or /readyz
- Re-check the --server URL and port
- 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
- Poll the server's /readyz before starting agents to avoid 503 races
- Automate token validation so 401s surface at deploy time
- Log the full '<url>: <status>' message — the URL and status carry all the diagnostics
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
- --server is required
- incompatible down-level server detected; servers must be upg
- all servers failed
- invalid username/password combination
- --token is required
AI-assisted analysis of k3s-io/k3s@6ba341e396 (2026-08-15).
Data as JSON: /api/errors/ed41df88694ccf26.
Report an issue: GitHub.