quarkusio/quarkus · error · AuthenticationFailedException

Token is opaque but the opaque token introspection is not al

Error message

Token is opaque but the opaque token introspection is not allowed

What it means

When the bearer token has no dot-separated JWT structure (opaque token), Quarkus must introspect it via the OIDC provider. This AuthenticationFailedException is thrown when the token is opaque but 'quarkus.oidc.token.allow-opaque-token-introspection' is false (the default), so introspection is refused outright.

Source

Thrown at extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcIdentityProvider.java:670

                    TokenType.CODE_FLOW_ACCESS_TOKEN, false, userInfo);
        } else {
            return NULL_CODE_ACCESS_TOKEN_UNI;
        }
    }

    private Uni<TokenVerificationResult> verifyTokenUni(Map<String, Object> requestData, TenantConfigContext resolvedContext,
            TokenCredential tokenCred, TokenType tokenType, boolean enforceAudienceVerification,
            UserInfo userInfo) {
        final String token = tokenCred.getToken();
        Long expiresIn = null;
        if (tokenType == TokenType.CODE_FLOW_ACCESS_TOKEN) {
            expiresIn = ((AuthorizationCodeTokens) requestData.get(AuthorizationCodeTokens.class.getName()))
                    .getAccessTokenExpiresIn();
        }
        if (OidcUtils.isOpaqueToken(token)) {
            if (!resolvedContext.oidcConfig().token().allowOpaqueTokenIntrospection()) {
                LOG.debug("Token is opaque but the opaque token introspection is not allowed");
                throw new AuthenticationFailedException(tokenMap(tokenCred));
            }
            // verify opaque access token with UserInfo if enabled and introspection URI is absent
            if (resolvedContext.oidcConfig().token().verifyAccessTokenWithUserInfo().orElse(false)
                    && resolvedContext.provider().getMetadata().getIntrospectionUri() == null) {
                if (userInfo == null) {
                    return Uni.createFrom().failure(
                            new AuthenticationFailedException("Opaque access token verification failed as user info is null.",
                                    tokenMap(tokenCred)));
                } else {
                    // valid token verification result
                    return Uni.createFrom().item(new TokenVerificationResult(null, null));
                }
            }
            LOG.debug("Starting the opaque token introspection");
            return introspectTokenUni(resolvedContext, token, tokenType, expiresIn, false);
        } else if (resolvedContext.provider().getMetadata().getJsonWebKeySetUri() == null
                || resolvedContext.oidcConfig().token().requireJwtIntrospectionOnly()) {
            // Verify JWT token with the remote introspection

View on GitHub (pinned to e1c734241f)

Solutions

  1. Set quarkus.oidc.token.allow-opaque-token-introspection=true.
  2. Ensure the provider's introspection endpoint is discoverable/known (well-known metadata) so introspection can run.
  3. Reconfigure the IdP client to issue JWT access tokens if local verification is preferred.
  4. If the token should be a JWT, check that you are validating the access token, not an opaque reference token.

Example fix

// application.properties
// before
quarkus.oidc.token.allow-opaque-token-introspection=false
// after
quarkus.oidc.token.allow-opaque-token-introspection=true
Defensive patterns

Strategy: validation

Validate before calling

// application.properties check before startup
if (tokenLooksOpaque(token) && !config.allowOpaqueTokenIntrospection()) {
    throw new IllegalStateException("Enable quarkus.oidc.token.allow-opaque-token-introspection");
}

Type guard

boolean isJwtToken(String token) {
    return token != null && token.chars().filter(c -> c == '.').count() == 2;
}

Try / catch

try {
    return authenticate(token);
} catch (AuthenticationFailedException e) {
    // fall back to a JWT-only flow or surface a config error
}

Prevention

When it happens

Trigger: quarkus.oidc.token.allow-opaque-token-introspection=false (default) while the token issued by the provider is an opaque (non-JWT) access token, verified via verifyTokenUni or verifyCodeFlowAccessTokenUni.

Common situations: Keycloak or another IdP configured to issue reference (opaque) tokens while the Quarkus app assumes JWTs; switching IdP or client profile from JWT to opaque tokens without updating Quarkus config.

Related errors


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