k3s-io/k3s · error

node password not set

Error message

node password not set

What it means

The second mandatory header check in getNodeInfo: <program>-Node-Password must be present and non-empty. Firing it means the node name header was fine but the shared node password header is missing, so verification cannot be attempted.

Solutions

  1. Ensure the node password file exists on the agent and is non-empty, then restart the agent so the header is sent.
  2. Include the header in manual requests: -H 'k3s-Node-Password: <password-from-file>'.
  3. Check proxies/ingress pass the custom header through.

Example fix

# before
curl -H 'k3s-Node-Name: node1' ...
# after
curl -H 'k3s-Node-Name: node1' -H "k3s-Node-Password: $(cat /var/lib/rancher/k3s/agent/etc/node-password)" ...
Defensive patterns

Strategy: validation

Validate before calling

if req.Header.Get(version.Program+"-Node-Password") == "" {
    return errors.New("missing " + version.Program + "-Node-Password header")
}

Prevention

When it happens

Trigger: Requests to the authenticated API that include k3s-Node-Name but omit k3s-Node-Password; agents whose password file is empty so they send no header; tools that manage only one of the two headers.

Common situations: Custom kubeconfig users configured with only a username; node password file (/var/lib/rancher/k3s/agent/etc/node-password) deleted or empty; header stripped by proxy like error 75.

Related errors


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

Appendix: source

Thrown at pkg/nodepassword/validate.go:115

}

// getNodeInfo returns node name, password, and user extracted
// from request headers and context. An error is returned
// if any critical fields are missing.
func getNodeInfo(req *http.Request) (*nodeInfo, error) {
	user, ok := request.UserFrom(req.Context())
	if !ok {
		return nil, errors.New("auth user not set")
	}

	nodeName := req.Header.Get(version.Program + "-Node-Name")
	if nodeName == "" {
		return nil, errors.New("node name not set")
	}

	nodePassword := req.Header.Get(version.Program + "-Node-Password")
	if nodePassword == "" {
		return nil, errors.New("node password not set")
	}

	return &nodeInfo{
		Name:     strings.ToLower(nodeName),
		Password: nodePassword,
		User:     user,
	}, nil
}

// verifyLocalPassword is used to validate the local node's password secret directly against the node password file, when the apiserver is unavailable.
// This is only used early in startup, when a control-plane node's agent is starting up without a functional apiserver.
func verifyLocalPassword(ctx context.Context, control *config.Control, mu *sync.Mutex, deferredNodes map[string]bool, node *nodeInfo) (string, int, error) {
	// do not attempt to verify the node password if the local host is not running an agent and does not have a node resource.
	// note that the agent certs and kubeconfigs are created even if the agent is disabled; the only thing that is skipped is starting the kubelet and container runtime.
	if control.DisableAgent {
		return node.Name, http.StatusOK, nil
	}

View on GitHub (pinned to 6ba341e396)