{"record":{"id":"894772ae9db90574","repo":"k3s-io/k3s","slug":"auth-user-not-set","errorCode":null,"errorMessage":"auth user not set","messagePattern":"auth user not set","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"pkg/nodepassword/validate.go","lineNumber":105,"sourceCode":"\t\t\t// allows nodes to join the cluster during outages caused by validating webhooks\n\t\t\t// blocking secret creation - if the outage requires new nodes to join in order to\n\t\t\t// run the webhook pods, we must fail open here to resolve the outage.\n\t\t\t// ref: github.com/k3s-io/k3s/issues/7654\n\t\t\tlogrus.Warnf(\"Failed to ensure node-password secret for node %s: %v\", node.Name, err)\n\t\t\treturn verifyRemotePassword(ctx, control, &mu, deferredNodes, node)\n\t\t}\n\n\t\treturn node.Name, http.StatusOK, nil\n\t}\n}\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}","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/nodepassword/validate.go#L87-L123","documentation":"getNodeInfo extracts the authenticated user from the request context via request.UserFrom; the node-password filter requires that upstream authentication has already run and stored a user. If the context carries no user (filter invoked on an unauthenticated path), the request fails immediately.","triggerScenarios":"The node-password authentication handler runs on a request that never passed the authentication filter - e.g. a miswired filter chain, a request sent to a port/path where authn is disabled, or a code change that reordered filters.","commonSituations":"Custom proxies or ingress stripping the authentication context; integration tests hitting the authn webhook directly; upgrades that changed the apiserver filter chain order.","solutions":["Send node-password requests through the authenticated flow (port 6443 with Authorization header / client certs), not to a plain HTTP listener.","Verify the request carries credentials (Authorization: Bearer ... or client cert) before it reaches this code.","If you maintain a custom filter chain, ensure the authentication filter runs before node-password verification."],"exampleFix":"# before: anonymous request, no authn context\ncurl http://node:6443/... -H 'k3s-Node-Name: node1' -H 'k3s-Node-Password: x'\n# after: authenticated request\ncurl -u node1:'password' https://node:6443/... -H 'k3s-Node-Name: node1' -H 'k3s-Node-Password: x'","handlingStrategy":"validation","validationCode":"// ensure authn has run before invoking node-password filter\nif _, ok := request.UserFrom(req.Context()); !ok {\n    return errors.New(\"request not authenticated; send Authorization header or client cert\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include credentials on requests handled by the authn filter chain.","In custom filter chains, order authentication before node-password verification."],"tags":["authentication","http","middleware"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}