spring-projects/spring-security · error · OAuth2AuthenticationException
invalid_token
invalid_token
Error message
OpenID Connect 1.0 Logout Request Parameter: id_token_hint
What it means
When processing an RP-initiated logout (OIDC Logout), OidcLogoutAuthenticationProvider looks up an OAuth2Authorization by the submitted id_token_hint using the ID token token type. If no authorization is found for that ID token, it throws invalid_token for id_token_hint — the logout request references a token the server does not recognize.
Source
Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationProvider.java:103
*/
public OidcLogoutAuthenticationProvider(RegisteredClientRepository registeredClientRepository,
OAuth2AuthorizationService authorizationService, SessionRegistry sessionRegistry) {
Assert.notNull(registeredClientRepository, "registeredClientRepository cannot be null");
Assert.notNull(authorizationService, "authorizationService cannot be null");
Assert.notNull(sessionRegistry, "sessionRegistry cannot be null");
this.registeredClientRepository = registeredClientRepository;
this.authorizationService = authorizationService;
this.sessionRegistry = sessionRegistry;
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
OidcLogoutAuthenticationToken oidcLogoutAuthentication = (OidcLogoutAuthenticationToken) authentication;
OAuth2Authorization authorization = this.authorizationService
.findByToken(oidcLogoutAuthentication.getIdTokenHint(), ID_TOKEN_TOKEN_TYPE);
if (authorization == null) {
throw createException(OAuth2ErrorCodes.INVALID_TOKEN, "id_token_hint");
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Retrieved authorization with ID Token");
}
OAuth2Authorization.Token<OidcIdToken> authorizedIdToken = authorization.getToken(OidcIdToken.class);
Assert.notNull(authorizedIdToken, "authorizedIdToken cannot be null");
if (authorizedIdToken.isInvalidated() || authorizedIdToken.isBeforeUse()) {
// Expired ID Token should be accepted
throw createException(OAuth2ErrorCodes.INVALID_TOKEN, "id_token_hint");
}
RegisteredClient registeredClient = this.registeredClientRepository
.findById(authorization.getRegisteredClientId());
Assert.notNull(registeredClient, "registeredClient cannot be null");
if (this.logger.isTraceEnabled()) {View on GitHub (pinned to 96852e8860)
Solutions
- Issue the logout from a client session whose ID token was issued by the same running authorization server
- Use a shared, persistent OAuth2AuthorizationService (e.g. JDBC/Redis) across all server instances
- Verify the id_token_hint value is the raw ID token JWT issued by this server, not a different token type
Example fix
// before authorizationService = new InMemoryOAuth2AuthorizationService(); // lost on restart // after authorizationService = new JdbcOAuth2AuthorizationService(jdbcOperations, registeredClientRepository);
Defensive patterns
Strategy: try-catch
Validate before calling
// Decode the id_token_hint JWT and confirm iss matches this authorization server before initiating logout
Try / catch
try {
authenticationManager.authenticate(new OidcLogoutAuthenticationToken(...));
} catch (AuthenticationException ex) {
// invalid_token for id_token_hint: re-authenticate the user and obtain a fresh ID token
} Prevention
- Use a shared persistent OAuth2AuthorizationService across instances
- Never reuse id_token_hint values from a previous server deployment or environment
- Send only ID tokens freshly issued by the same server
When it happens
Trigger: Submitting a logout request to the OIDC logout endpoint with an id_token_hint that was not issued by this authorization server, was issued by a different server instance/authorizationService store, or whose session/authorization record was deleted.
Common situations: Multi-instance deployments where the in-memory authorization service is not shared (token issued by another node); restarting the server with an in-memory OAuth2AuthorizationService so previously issued ID tokens are unknown; sending an id_token_hint from a different environment (staging token to prod).
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/bfa375763e902d29.
Report an issue: GitHub.