{"record":{"id":"7f65a656ff9a9491","repo":"quarkusio/quarkus","slug":"authenticationfailedexception-7f65a6","errorCode":null,"errorMessage":"AuthenticationFailedException","messagePattern":"AuthenticationFailedException","errorType":"http","errorClass":"AuthenticationFailedException","httpStatus":401,"severity":"error","filePath":"extensions/elytron-security/runtime/src/main/java/io/quarkus/elytron/security/runtime/ElytronTokenIdentityProvider.java","lineNumber":52,"sourceCode":"    SecurityDomain domain;\n\n    @Override\n    public Class<TokenAuthenticationRequest> getRequestType() {\n        return TokenAuthenticationRequest.class;\n    }\n\n    @Override\n    public Uni<SecurityIdentity> authenticate(TokenAuthenticationRequest request,\n            AuthenticationRequestContext context) {\n        return context.runBlocking(new Supplier<SecurityIdentity>() {\n            @Override\n            public SecurityIdentity get() {\n                org.wildfly.security.auth.server.SecurityIdentity result;\n                try {\n                    result = domain.authenticate(new BearerTokenEvidence(request.getToken().getToken()));\n\n                    if (result == null) {\n                        throw new AuthenticationFailedException();\n                    }\n                    QuarkusSecurityIdentity.Builder builder = QuarkusSecurityIdentity.builder();\n                    for (Attributes.Entry entry : result.getAttributes().entries()) {\n                        builder.addAttribute(entry.getKey(), entry);\n                    }\n                    builder.setPrincipal(result.getPrincipal());\n                    for (String i : result.getRoles()) {\n                        builder.addRole(i);\n                    }\n                    builder.addCredential(request.getToken());\n                    return builder.build();\n                } catch (RealmUnavailableException e) {\n                    throw new RuntimeException(e);\n                } catch (SecurityException e) {\n                    log.debug(\"Authentication failed\", e);\n                    throw new AuthenticationFailedException(e);\n                }\n            }","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/elytron-security/runtime/src/main/java/io/quarkus/elytron/security/runtime/ElytronTokenIdentityProvider.java#L34-L70","documentation":"ElytronTokenIdentityProvider.authenticate() throws AuthenticationFailedException when domain.authenticate(new BearerTokenEvidence(token)) returns null — no realm validated the bearer token. This is the token-based analogue of a bad username/password: the token is unknown, expired, wrong audience/issuer, or no token-capable realm is registered in the domain.","triggerScenarios":"Calling authentication with a bearer token where the domain returns null: token signature verification fails silently to 'no identity', token already expired, token issued by a different issuer, or no realm supporting BearerTokenEvidence exists in the SecurityDomain.","commonSituations":"Expired JWT access token sent by the client; client sends a token from a different environment (dev vs prod issuer); quarkus-elytron-security-oauth2 / token realm not configured so the domain has no realm to accept BearerTokenEvidence; clock skew between token issuer and verifier.","solutions":["Verify the token is unexpired and issued by the expected issuer for the configured realm.","Confirm a token-capable realm (e.g. JWT/token realm) is registered in the SecurityDomain; otherwise authenticate always returns null.","Check clock synchronization/skew if tokens are rejected shortly after issuance.","Re-obtain a fresh access token; test the token with the issuer's introspection/verification endpoint."],"exampleFix":"// before: reusing a stale cached token\ncredentials = new TokenCredential(oldToken);\n// after: refresh the token before authenticating\ncredentials = new TokenCredential(tokenRefresher.getFreshAccessToken());","handlingStrategy":"validation","validationCode":"// before authenticating, sanity-check the bearer token\npublic static boolean tokenLooksValid(String jwt) {\n    if (jwt == null || jwt.isBlank()) return false;\n    String[] parts = jwt.split(\"\\\\.\");\n    if (parts.length != 3) return false;\n    long exp = parseExpClaim(jwt);\n    return exp > System.currentTimeMillis() / 1000;\n}","typeGuard":"boolean isBearerToken(Object t) { return t instanceof TokenCredential && ((TokenCredential) t).getToken() != null; }","tryCatchPattern":null,"preventionTips":["Refresh tokens before expiry; don't cache access tokens beyond their lifetime.","Confirm a token-capable realm is registered in the SecurityDomain at startup.","Synchronize clocks (NTP) between token issuer and the verifying service.","Test with tokens from the same issuer/environment as the configured realm."],"tags":["security","bearer-token","authentication","elytron"],"backgroundTag":"bearer-token-validation-failed","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}