spring-projects/spring-security · error · OAuth2AuthenticationException
invalid_request
invalid_request
Error message
invalid_request
What it means
OAuth2LoginAuthenticationFilter.attemptAuthentication throws OAuth2AuthenticationException with code invalid_request when the callback request does not contain a recognizable OAuth2 authorization response: neither code+state nor error parameters are present in the request's parameter map.
Source
Thrown at oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/OAuth2LoginAuthenticationFilter.java:172
* the authentication requests
* @since 5.1
*/
public OAuth2LoginAuthenticationFilter(ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository, String filterProcessesUrl) {
super(filterProcessesUrl);
Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null");
Assert.notNull(authorizedClientRepository, "authorizedClientRepository cannot be null");
this.clientRegistrationRepository = clientRegistrationRepository;
this.authorizedClientRepository = authorizedClientRepository;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
MultiValueMap<String, String> params = OAuth2AuthorizationResponseUtils.toMultiMap(request.getParameterMap());
if (!OAuth2AuthorizationResponseUtils.isAuthorizationResponse(params)) {
OAuth2Error oauth2Error = new OAuth2Error(OAuth2ErrorCodes.INVALID_REQUEST);
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
}
OAuth2AuthorizationRequest authorizationRequest = this.authorizationRequestRepository
.removeAuthorizationRequest(request, response);
if (authorizationRequest == null) {
OAuth2Error oauth2Error = new OAuth2Error(AUTHORIZATION_REQUEST_NOT_FOUND_ERROR_CODE);
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
}
String registrationId = authorizationRequest.getAttribute(OAuth2ParameterNames.REGISTRATION_ID);
Assert.hasText(registrationId, "registrationId cannot be empty");
ClientRegistration clientRegistration = this.clientRegistrationRepository.findByRegistrationId(registrationId);
if (clientRegistration == null) {
OAuth2Error oauth2Error = new OAuth2Error(CLIENT_REGISTRATION_NOT_FOUND_ERROR_CODE,
"Client Registration not found with Id: " + registrationId, null);
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
}
// @formatter:off
String redirectUri = UriComponentsBuilder.fromUriString(UrlUtils.buildFullRequestUrl(request))
.replaceQuery(null)View on GitHub (pinned to 96852e8860)
Solutions
- Ensure the authorization request was initiated via /oauth2/authorization/{registrationId} so the IdP redirects back with code and state
- Check the IdP's registered redirect URI matches exactly and that no proxy strips query parameters
- Point the user back to the login entry point instead of exposing the redirect URI as a navigable page
Defensive patterns
Strategy: validation
Validate before calling
MultiValueMap<String,String> params = OAuth2AuthorizationResponseUtils.toMultiMap(request.getParameterMap());
if (!OAuth2AuthorizationResponseUtils.isAuthorizationResponse(params)) {
response.sendRedirect("/oauth2/authorization/myclient");
return;
} Try / catch
catch (OAuth2AuthenticationException e) {
if (OAuth2ErrorCodes.INVALID_REQUEST.equals(e.getError().getErrorCode())) {
// restart login flow / redirect to authorization endpoint
}
} Prevention
- Never expose the redirect URI as a navigable/bookmarkable page
- Ensure proxies/LBs preserve query strings
- Verify the IdP always redirects back with code+state
When it happens
Trigger: A request reaches /login/oauth2/code/{registrationId} without query parameters code & state (or error/error_description) — e.g. a user bookmarking or manually hitting the redirect URI, or the IdP redirecting without parameters.
Common situations: Users bookmarking the redirect URI; load balancers or proxies stripping query strings; misconfigured redirect-uri template so the filter's matcher catches unrelated requests.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- authorization_request_not_found
- Unable to create an {OAuth2AuthorizedClientManager} bean. Ex
- invalid_dpop_proof
- invalid_scope
- oidc_provider_not_configured
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/24e3e2edf4147402.
Report an issue: GitHub.