{"record":{"id":"bfa375763e902d29","repo":"spring-projects/spring-security","slug":"invalid-token-bfa375","errorCode":"invalid_token","errorMessage":"OpenID Connect 1.0 Logout Request Parameter: id_token_hint","messagePattern":"OpenID Connect 1\\.0 Logout Request Parameter: id_token_hint","errorType":"error_code","errorClass":"OAuth2AuthenticationException","httpStatus":400,"severity":"error","filePath":"oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationProvider.java","lineNumber":103,"sourceCode":"\t */\n\tpublic OidcLogoutAuthenticationProvider(RegisteredClientRepository registeredClientRepository,\n\t\t\tOAuth2AuthorizationService authorizationService, SessionRegistry sessionRegistry) {\n\t\tAssert.notNull(registeredClientRepository, \"registeredClientRepository cannot be null\");\n\t\tAssert.notNull(authorizationService, \"authorizationService cannot be null\");\n\t\tAssert.notNull(sessionRegistry, \"sessionRegistry cannot be null\");\n\t\tthis.registeredClientRepository = registeredClientRepository;\n\t\tthis.authorizationService = authorizationService;\n\t\tthis.sessionRegistry = sessionRegistry;\n\t}\n\n\t@Override\n\tpublic Authentication authenticate(Authentication authentication) throws AuthenticationException {\n\t\tOidcLogoutAuthenticationToken oidcLogoutAuthentication = (OidcLogoutAuthenticationToken) authentication;\n\n\t\tOAuth2Authorization authorization = this.authorizationService\n\t\t\t.findByToken(oidcLogoutAuthentication.getIdTokenHint(), ID_TOKEN_TOKEN_TYPE);\n\t\tif (authorization == null) {\n\t\t\tthrow createException(OAuth2ErrorCodes.INVALID_TOKEN, \"id_token_hint\");\n\t\t}\n\n\t\tif (this.logger.isTraceEnabled()) {\n\t\t\tthis.logger.trace(\"Retrieved authorization with ID Token\");\n\t\t}\n\n\t\tOAuth2Authorization.Token<OidcIdToken> authorizedIdToken = authorization.getToken(OidcIdToken.class);\n\t\tAssert.notNull(authorizedIdToken, \"authorizedIdToken cannot be null\");\n\t\tif (authorizedIdToken.isInvalidated() || authorizedIdToken.isBeforeUse()) {\n\t\t\t// Expired ID Token should be accepted\n\t\t\tthrow createException(OAuth2ErrorCodes.INVALID_TOKEN, \"id_token_hint\");\n\t\t}\n\n\t\tRegisteredClient registeredClient = this.registeredClientRepository\n\t\t\t.findById(authorization.getRegisteredClientId());\n\t\tAssert.notNull(registeredClient, \"registeredClient cannot be null\");\n\n\t\tif (this.logger.isTraceEnabled()) {","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationProvider.java#L85-L121","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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"],"exampleFix":"// before\nauthorizationService = new InMemoryOAuth2AuthorizationService(); // lost on restart\n// after\nauthorizationService = new JdbcOAuth2AuthorizationService(jdbcOperations, registeredClientRepository);","handlingStrategy":"try-catch","validationCode":"// Decode the id_token_hint JWT and confirm iss matches this authorization server before initiating logout","typeGuard":null,"tryCatchPattern":"try {\n    authenticationManager.authenticate(new OidcLogoutAuthenticationToken(...));\n} catch (AuthenticationException ex) {\n    // invalid_token for id_token_hint: re-authenticate the user and obtain a fresh ID token\n}","preventionTips":["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"],"tags":["oauth2","oidc","logout","id-token"],"backgroundTag":"resource-not-found","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}