quarkusio/quarkus · warning · AuthenticationFailedException
Required ID token is not returned in the refresh token grant
Error message
Required ID token is not returned in the refresh token grant response, re-authentication is required
What it means
When a refresh token grant response arrives and auto-refresh was not triggered proactively, if the application requires an ID token (isIdTokenRequired) but the provider did not return one alongside the new access token, Quarkus cannot refresh the session and throws AuthenticationFailedException carrying the current ID token, forcing the user to re-authenticate via a fresh code flow.
Source
Thrown at extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/CodeAuthenticationMechanism.java:1581
private Uni<AuthorizationCodeTokens> refreshTokensUni(TenantConfigContext configContext,
String currentIdToken, String refreshToken, boolean autoRefresh) {
return configContext.provider().refreshTokens(refreshToken).onItem()
.transform(new Function<AuthorizationCodeTokens, AuthorizationCodeTokens>() {
@Override
public AuthorizationCodeTokens apply(AuthorizationCodeTokens tokens) {
if (tokens.getRefreshToken() == null) {
tokens.setRefreshToken(refreshToken);
}
if (tokens.getIdToken() == null) {
if (autoRefresh) {
// Auto-refresh is triggered while current ID token is still valid, continue using it.
tokens.setIdToken(currentIdToken);
} else if (isIdTokenRequired(configContext)) {
LOG.debugf(
"Required ID token is not returned in the refresh token grant response, re-authentication is required");
throw new AuthenticationFailedException(tokenMap(currentIdToken));
} else {
if (!isInternalIdToken(currentIdToken, configContext)) {
LOG.debugf(
"OIDC provider issued an ID token after the authorization code flow completion but did not refresh it,"
+ " an internal ID token will be generated");
}
tokens.setIdToken(generateInternalIdToken(configContext, null, currentIdToken,
tokens.getAccessTokenExpiresIn()));
}
}
return tokens;
}
});
}
private Uni<AuthorizationCodeTokens> getCodeFlowTokensUni(RoutingContext context, TenantConfigContext configContext,View on GitHub (pinned to e1c734241f)
Solutions
- Allow Quarkus to keep and reuse the existing ID token across refreshes (do not force re-verification of a fresh ID token) or relax the ID-token-required setting for the tenant.
- Configure quarkus.oidc.token.verify-access-token-with-user-info=false / adjust token settings so the old ID token remains valid for session purposes.
- Upgrade or reconfigure the OIDC provider to return id_token in refresh token grant responses.
- If acceptable, shorten the session so users re-authenticate via the code flow when the ID token expires.
Example fix
// before quarkus.oidc.authentication.id-token-required=true // after (if provider omits id_token on refresh and session can rely on access token) quarkus.oidc.authentication.id-token-required=false
Defensive patterns
Strategy: fallback
Validate before calling
// Probe provider behavior: does refresh_token grant return id_token?
Map<String, String> resp = tokenRequest("refresh_token", refreshToken);
if (isIdTokenRequired() && !resp.containsKey("id_token")) {
log.warn("Provider omits id_token on refresh; configure session to reuse the original ID token");
} Try / catch
try {
return refreshSession(refreshToken);
} catch (AuthenticationFailedException e) {
if (e.getMessage() != null && e.getMessage().contains("Required ID token is not returned")) {
// fall back to re-authentication
redirectToAuthorizationEndpoint();
return null;
}
throw e;
} Prevention
- Verify with a manual curl refresh_token grant whether your provider returns id_token.
- Keep the originally issued ID token for session identity instead of requiring a new one per refresh.
- Test refresh flows after provider upgrades; grant response shape can change.
When it happens
Trigger: Token refresh (session expiry or token refresh in CodeAuthenticationMechanism) returns a token map without id_token while isIdTokenRequired(configContext) is true and autoRefresh is false.
Common situations: OIDC providers that omit id_token in refresh_token grant responses (some providers only return access_token); configuring quarkus.oidc.token.refresh-expired or requiring ID token verification with such providers; provider policy changes after an upgrade.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- ID Token is required to contain 'exp' and 'iat' claims
- Access token expires_in property in the session cookie must
- Refresh token can only be used with the refresh token grant
- UserInfo is not required for OIDC tenant '%s' but it will be
- Refresh token values are not equal
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/9540b3c62270f4a9.
Report an issue: GitHub.