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

  1. Ensure the authorization request was initiated via /oauth2/authorization/{registrationId} so the IdP redirects back with code and state
  2. Check the IdP's registered redirect URI matches exactly and that no proxy strips query parameters
  3. 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

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


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/24e3e2edf4147402. Report an issue: GitHub.