{"record":{"id":"188f9cdd3f5b8806","repo":"k3s-io/k3s","slug":"node-password-not-set","errorCode":null,"errorMessage":"node password not set","messagePattern":"node password not set","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"pkg/nodepassword/validate.go","lineNumber":115,"sourceCode":"}\n\n// getNodeInfo returns node name, password, and user extracted\n// from request headers and context. An error is returned\n// if any critical fields are missing.\nfunc getNodeInfo(req *http.Request) (*nodeInfo, error) {\n\tuser, ok := request.UserFrom(req.Context())\n\tif !ok {\n\t\treturn nil, errors.New(\"auth user not set\")\n\t}\n\n\tnodeName := req.Header.Get(version.Program + \"-Node-Name\")\n\tif nodeName == \"\" {\n\t\treturn nil, errors.New(\"node name not set\")\n\t}\n\n\tnodePassword := req.Header.Get(version.Program + \"-Node-Password\")\n\tif nodePassword == \"\" {\n\t\treturn nil, errors.New(\"node password not set\")\n\t}\n\n\treturn &nodeInfo{\n\t\tName:     strings.ToLower(nodeName),\n\t\tPassword: nodePassword,\n\t\tUser:     user,\n\t}, nil\n}\n\n// verifyLocalPassword is used to validate the local node's password secret directly against the node password file, when the apiserver is unavailable.\n// This is only used early in startup, when a control-plane node's agent is starting up without a functional apiserver.\nfunc verifyLocalPassword(ctx context.Context, control *config.Control, mu *sync.Mutex, deferredNodes map[string]bool, node *nodeInfo) (string, int, error) {\n\t// do not attempt to verify the node password if the local host is not running an agent and does not have a node resource.\n\t// 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.\n\tif control.DisableAgent {\n\t\treturn node.Name, http.StatusOK, nil\n\t}\n","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/nodepassword/validate.go#L97-L133","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the node password file exists on the agent and is non-empty, then restart the agent so the header is sent.","Include the header in manual requests: -H 'k3s-Node-Password: <password-from-file>'.","Check proxies/ingress pass the custom header through."],"exampleFix":"# before\ncurl -H 'k3s-Node-Name: node1' ...\n# after\ncurl -H 'k3s-Node-Name: node1' -H \"k3s-Node-Password: $(cat /var/lib/rancher/k3s/agent/etc/node-password)\" ...","handlingStrategy":"validation","validationCode":"if req.Header.Get(version.Program+\"-Node-Password\") == \"\" {\n    return errors.New(\"missing \" + version.Program + \"-Node-Password header\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure the agent's node password file exists and is non-empty before restarts.","Test header propagation end-to-end through any gateway in front of the API."],"tags":["authentication","http-headers","node"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}