{"record":{"id":"72ea31d0b73a834f","repo":"k3s-io/k3s","slug":"invalid-username-password-combination","errorCode":null,"errorMessage":"invalid username/password combination","messagePattern":"invalid username/password combination","errorType":"http","errorClass":null,"httpStatus":401,"severity":"error","filePath":"pkg/authenticator/basicauth/basicauth.go","lineNumber":36,"sourceCode":"\nimport (\n\t\"errors\"\n\t\"net/http\"\n\n\t\"k8s.io/apiserver/pkg/authentication/authenticator\"\n)\n\n// Authenticator authenticates requests using basic auth\ntype Authenticator struct {\n\tauth Password\n}\n\n// New returns a request authenticator that validates credentials using the provided password authenticator\nfunc New(auth Password) *Authenticator {\n\treturn &Authenticator{auth}\n}\n\nvar errInvalidAuth = errors.New(\"invalid username/password combination\")\n\n// AuthenticateRequest authenticates the request using the \"Authorization: Basic\" header in the request\nfunc (a *Authenticator) AuthenticateRequest(req *http.Request) (*authenticator.Response, bool, error) {\n\tusername, password, found := req.BasicAuth()\n\tif !found {\n\t\treturn nil, false, nil\n\t}\n\n\tresp, ok, err := a.auth.AuthenticatePassword(req.Context(), username, password)\n\n\t// If the password authenticator didn't error, provide a default error\n\tif !ok && err == nil {\n\t\terr = errInvalidAuth\n\t}\n\n\treturn resp, ok, err\n}\n","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/authenticator/basicauth/basicauth.go#L18-L54","documentation":"The basicauth authenticator extracts the Authorization: Basic header and delegates to a Password authenticator. If the password check completes without an internal error but the credentials are simply wrong (ok == false, err == nil), it substitutes this default error so callers get a meaningful 401 cause instead of a bare 'not authenticated'. Not-found headers return no error at all, so this error specifically means bad credentials were presented.","triggerScenarios":"Calling a k3s supervisor API endpoint guarded by basic auth with a wrong username or password: kubectl --username/--password against the supervisor, curl -u with stale creds, or automation using rotated credentials.","commonSituations":"Password rotated on the cluster but cached in kubeconfig/kubectl; CI secrets out of date; typos in username/password; using the wrong user for the endpoint.","solutions":["Correct the credentials (update kubeconfig users, curl -u, or CI secrets) to the current username/password","If credentials were lost, reset/reissue them through the cluster's user management rather than retrying","Prefer token-based auth (K3S_TOKEN / bearer tokens) for automation to avoid stale basic-auth caches"],"exampleFix":"# before\ncurl -u admin:wrongpass -k https://127.0.0.1:6443/... # -> invalid username/password combination\n\n# after\ncurl -u admin:$(cat current-pass) -k https://127.0.0.1:6443/...","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"resp, ok, err := authn.AuthenticateRequest(req)\nif err != nil {\n    if errors.Is(err, basicauth.ErrInvalidAuth) || err.Error() == \"invalid username/password combination\" {\n        http.Error(w, \"401 Unauthorized\", http.StatusUnauthorized) // do not leak which part failed\n        return\n    }\n    http.Error(w, \"500 Internal Server Error\", http.StatusInternalServerError)\n}","preventionTips":["Rotate credentials and kubeconfig entries together so caches never go stale","Prefer bearer tokens over basic auth in automation","Return generic 401s to callers; log details server-side only"],"tags":["authentication","basic-auth","http","security","supervisor"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}