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.

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)

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.