{"record":{"id":"ce0b0be2761daba3","repo":"quarkusio/quarkus","slug":"token-issued-to-client-s-is-not-active","errorCode":null,"errorMessage":"Token issued to client %s is not active","messagePattern":"Token issued to client (.+?) is not active","errorType":"exception","errorClass":"AuthenticationFailedException","httpStatus":401,"severity":"error","filePath":"extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcProvider.java","lineNumber":416,"sourceCode":"\n            throw new AuthenticationFailedException(errorMessage, tokenMap(token, tokenType));\n        }\n        return client.introspectAccessToken(token).onItemOrFailure()\n                .transform(new BiFunction<TokenIntrospection, Throwable, TokenIntrospection>() {\n\n                    @Override\n                    public TokenIntrospection apply(TokenIntrospection introspectionResult, Throwable t) {\n                        if (t != null) {\n                            throw new AuthenticationFailedException(t, tokenMap(token, tokenType));\n                        }\n                        Long introspectionExpiresIn = introspectionResult.getLong(OidcConstants.INTROSPECTION_TOKEN_EXP);\n                        if (introspectionExpiresIn == null && expiresIn != null) {\n                            // expires_in is relative to the current time\n                            introspectionExpiresIn = now() + expiresIn;\n                        }\n                        if (!introspectionResult.isActive()) {\n                            verifyTokenExpiry(token, tokenType, introspectionExpiresIn);\n                            throw new AuthenticationFailedException(\n                                    String.format(\"Token issued to client %s is not active\", oidcConfig.clientId().get()),\n                                    tokenMap(token, tokenType));\n                        }\n                        verifyTokenExpiry(token, tokenType, introspectionExpiresIn);\n                        try {\n                            verifyTokenAge(introspectionResult.getLong(OidcConstants.INTROSPECTION_TOKEN_IAT));\n                        } catch (InvalidJwtException ex) {\n                            throw new AuthenticationFailedException(ex, tokenMap(token, tokenType));\n                        }\n\n                        if (requiredClaims != null) {\n                            for (Map.Entry<String, Set<String>> requiredClaim : requiredClaims.entrySet()) {\n                                final String requiredClaimName = requiredClaim.getKey();\n                                if (!introspectionResult.contains(requiredClaimName)) {\n                                    LOG.debugf(\"Introspection claim %s is missing\", requiredClaimName);\n                                    throw new AuthenticationFailedException(tokenMap(token, tokenType));\n                                }\n                                final Set<String> requiredClaimValues = requiredClaim.getValue();","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcProvider.java#L398-L434","documentation":"After introspecting a token, Quarkus checks the 'active' boolean from the introspection response. This AuthenticationFailedException is thrown when the introspection endpoint reports the token as not active (revoked, expired, or not yet valid), even before other checks run.","triggerScenarios":"introspectToken's apply() receives TokenIntrospection with active=false — typically a revoked or expired access token presented as a Bearer token or code-flow token.","commonSituations":"User logged out / admin revoked the session but the client keeps sending the cached token; token expired server-side while the client cache hasn't refreshed; introspecting the wrong token type (e.g. ID token).","solutions":["Obtain a fresh access token (refresh flow or re-authentication) — the presented token is invalid.","Clear the client-side token cache so revoked tokens are not reused.","Check why the token was deactivated (logout, revocation endpoint, session lifetime).","If the wrong token is being sent, configure the client to send the access token, not the ID token."],"exampleFix":"// before: reuse cached token indefinitely\nString token = cachedToken;\n// after: refresh when expired/revoked\nif (isExpiredOrInactive(token)) { token = refreshAccessToken(); }","handlingStrategy":"try-catch","validationCode":"TokenIntrospection ti = client.introspectAccessToken(token).await().indefinitely();\nif (!ti.isActive()) {\n    // refresh or re-authenticate before retrying the request\n}","typeGuard":"boolean isActiveToken(TokenIntrospection ti) {\n    return ti != null && ti.isActive();\n}","tryCatchPattern":"try {\n    return authenticate(token);\n} catch (AuthenticationFailedException e) {\n    // token inactive: start refresh-token flow or force re-login\n}","preventionTips":["Never cache access tokens beyond their expiry; refresh proactively","Treat introspection active=false as 'get a new token', not as a retryable error","Ensure you send the access token (not the ID token) to resource endpoints","Handle logout/revocation events by clearing client-side token caches"],"tags":["oidc","introspection","revoked-token","token-inactive"],"backgroundTag":"token-inactive-or-revoked","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"}