quarkusio/quarkus · error · AuthenticationFailedException

AuthenticationFailedException

Error message

AuthenticationFailedException

What it means

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.

Source

Thrown at extensions/elytron-security/runtime/src/main/java/io/quarkus/elytron/security/runtime/ElytronTokenIdentityProvider.java:52

    SecurityDomain domain;

    @Override
    public Class<TokenAuthenticationRequest> getRequestType() {
        return TokenAuthenticationRequest.class;
    }

    @Override
    public Uni<SecurityIdentity> authenticate(TokenAuthenticationRequest request,
            AuthenticationRequestContext context) {
        return context.runBlocking(new Supplier<SecurityIdentity>() {
            @Override
            public SecurityIdentity get() {
                org.wildfly.security.auth.server.SecurityIdentity result;
                try {
                    result = domain.authenticate(new BearerTokenEvidence(request.getToken().getToken()));

                    if (result == null) {
                        throw new AuthenticationFailedException();
                    }
                    QuarkusSecurityIdentity.Builder builder = QuarkusSecurityIdentity.builder();
                    for (Attributes.Entry entry : result.getAttributes().entries()) {
                        builder.addAttribute(entry.getKey(), entry);
                    }
                    builder.setPrincipal(result.getPrincipal());
                    for (String i : result.getRoles()) {
                        builder.addRole(i);
                    }
                    builder.addCredential(request.getToken());
                    return builder.build();
                } catch (RealmUnavailableException e) {
                    throw new RuntimeException(e);
                } catch (SecurityException e) {
                    log.debug("Authentication failed", e);
                    throw new AuthenticationFailedException(e);
                }
            }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Verify the token is unexpired and issued by the expected issuer for the configured realm.
  2. Confirm a token-capable realm (e.g. JWT/token realm) is registered in the SecurityDomain; otherwise authenticate always returns null.
  3. Check clock synchronization/skew if tokens are rejected shortly after issuance.
  4. Re-obtain a fresh access token; test the token with the issuer's introspection/verification endpoint.

Example fix

// before: reusing a stale cached token
credentials = new TokenCredential(oldToken);
// after: refresh the token before authenticating
credentials = new TokenCredential(tokenRefresher.getFreshAccessToken());
Defensive patterns

Strategy: validation

Validate before calling

// before authenticating, sanity-check the bearer token
public static boolean tokenLooksValid(String jwt) {
    if (jwt == null || jwt.isBlank()) return false;
    String[] parts = jwt.split("\\.");
    if (parts.length != 3) return false;
    long exp = parseExpClaim(jwt);
    return exp > System.currentTimeMillis() / 1000;
}

Type guard

boolean isBearerToken(Object t) { return t instanceof TokenCredential && ((TokenCredential) t).getToken() != null; }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/7f65a656ff9a9491. Report an issue: GitHub.