{"record":{"id":"fc18984218190a3d","repo":"spring-projects/spring-security","slug":"invalid-id-token-fc1898","errorCode":"invalid_id_token","errorMessage":"Missing (required) ID Token in Token Response for Client Registration: ${registrationId}","messagePattern":"Missing \\(required\\) ID Token in Token Response for Client Registration: (.+?)","errorType":"error_code","errorClass":"OAuth2AuthenticationException","httpStatus":null,"severity":"error","filePath":"oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/authentication/OidcAuthorizationCodeAuthenticationProvider.java","lineNumber":158,"sourceCode":"\t\t\t.getAuthorizationResponse();\n\t\tif (authorizationResponse.statusError()) {\n\t\t\tOAuth2Error error = authorizationResponse.getError();\n\t\t\tAssert.notNull(error, \"error cannot be null when status is error\");\n\t\t\tthrow new OAuth2AuthenticationException(error, error.toString());\n\t\t}\n\t\tif (!Objects.equals(authorizationResponse.getState(), authorizationRequest.getState())) {\n\t\t\tOAuth2Error oauth2Error = new OAuth2Error(INVALID_STATE_PARAMETER_ERROR_CODE);\n\t\t\tthrow new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());\n\t\t}\n\t\tOAuth2AccessTokenResponse accessTokenResponse = getResponse(authorizationCodeAuthentication);\n\t\tClientRegistration clientRegistration = authorizationCodeAuthentication.getClientRegistration();\n\t\tMap<String, Object> additionalParameters = accessTokenResponse.getAdditionalParameters();\n\t\tif (!additionalParameters.containsKey(OidcParameterNames.ID_TOKEN)) {\n\t\t\tOAuth2Error invalidIdTokenError = new OAuth2Error(INVALID_ID_TOKEN_ERROR_CODE,\n\t\t\t\t\t\"Missing (required) ID Token in Token Response for Client Registration: \"\n\t\t\t\t\t\t\t+ clientRegistration.getRegistrationId(),\n\t\t\t\t\tnull);\n\t\t\tthrow new OAuth2AuthenticationException(invalidIdTokenError, invalidIdTokenError.toString());\n\t\t}\n\t\tOidcIdToken idToken = createOidcToken(clientRegistration, accessTokenResponse);\n\t\tvalidateNonce(authorizationRequest, idToken);\n\t\tOidcUser oidcUser = this.userService.loadUser(new OidcUserRequest(clientRegistration,\n\t\t\t\taccessTokenResponse.getAccessToken(), idToken, additionalParameters));\n\t\tAssert.notNull(oidcUser, \"oidcUser cannot be null\");\n\t\tCollection<? extends GrantedAuthority> mappedAuthorities = this.authoritiesMapper\n\t\t\t.mapAuthorities(oidcUser.getAuthorities());\n\t\tOAuth2LoginAuthenticationToken authenticationResult = new OAuth2LoginAuthenticationToken(\n\t\t\t\tauthorizationCodeAuthentication.getClientRegistration(),\n\t\t\t\tauthorizationCodeAuthentication.getAuthorizationExchange(), oidcUser, mappedAuthorities,\n\t\t\t\taccessTokenResponse.getAccessToken(), accessTokenResponse.getRefreshToken());\n\t\tauthenticationResult.setDetails(authorizationCodeAuthentication.getDetails());\n\t\treturn authenticationResult;\n\t}\n\n\tprivate OAuth2AccessTokenResponse getResponse(OAuth2LoginAuthenticationToken authorizationCodeAuthentication) {\n\t\ttry {","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/authentication/OidcAuthorizationCodeAuthenticationProvider.java#L140-L176","documentation":"OpenID Connect requires the token response to include an id_token in additionalParameters. When the token endpoint's response lacks it, the OIDC provider cannot build an OidcUser, so invalid_id_token is thrown with the registration id in the message.","triggerScenarios":"Thrown in authenticate() when accessTokenResponse.getAdditionalParameters() does not contain OidcParameterNames.ID_TOKEN after a successful token exchange with an OIDC provider.","commonSituations":"Registration configured with scope=openid missing (so the OP issues a plain OAuth2 token, not an OIDC one), the OP not actually being an OIDC provider, a non-standard token endpoint that puts id_token elsewhere, or using authorization_code with a provider that only supports the implicit/hybrid flow.","solutions":["Ensure the openid scope is requested: .scope(\"openid\", \"profile\", \"email\") in the client registration.","Verify the tokenUri/issuer actually belongs to an OIDC provider that returns id_token for the code flow.","Check that no custom token response client strips additionalParameters from the response.","If the provider is OAuth2-only, drop OIDC login and use plain OAuth2Login without OidcUserService."],"exampleFix":"// before\n registration.scope(\"read:user\");\n// after\n registration.scope(\"openid\", \"profile\", \"email\");","handlingStrategy":"validation","validationCode":"// assert OIDC readiness at startup\nClientRegistration reg = ...;\nSet<String> scopes = reg.getScopes();\nif (reg.getAuthorizationGrantType() == AuthorizationGrantType.AUTHORIZATION_CODE\n        && !scopes.contains(\"openid\")) {\n    throw new IllegalStateException(\"OIDC login requires the 'openid' scope; registration \"\n        + reg.getRegistrationId() + \" does not request it\");\n}","typeGuard":null,"tryCatchPattern":"catch (OAuth2AuthenticationException ex) { if (\"invalid_id_token\".equals(ex.getError().getErrorCode())) { log.error(\"Provider did not return id_token; is this an OIDC provider and is 'openid' scoped?\"); } throw ex; }","preventionTips":["Always include the openid scope for OIDC client registrations.","Confirm the provider is OIDC-compliant (has .well-known/openid-configuration).","Don't override the token response client in ways that drop additionalParameters.","Verify with a raw token-endpoint curl that id_token appears in the response."],"tags":["oidc","id-token","oauth2","spring-security"],"backgroundTag":"missing-required-argument","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"}