spring-projects/spring-security · error · OAuth2AuthorizationCodeRequestAuthenticationException

invalid_request

invalid_request

Error message

OAuth 2.0 Parameter: request_uri

What it means

Thrown by OAuth2AuthorizationCodeRequestAuthenticationProvider.createException() when the authorization request carries a request_uri parameter (RFC 9126 Pushed Authorization Requests flow-through) that cannot be parsed into a valid OAuth2PushedAuthorizationRequestUri. The error is invalid_request naming the request_uri parameter.

Source

Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationProvider.java:138

		this.registeredClientRepository = registeredClientRepository;
		this.authorizationService = authorizationService;
		this.authorizationConsentService = authorizationConsentService;
	}

	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication = (OAuth2AuthorizationCodeRequestAuthenticationToken) authentication;

		OAuth2Authorization pushedAuthorization = null;
		String requestUri = (String) authorizationCodeRequestAuthentication.getAdditionalParameters()
			.get(OAuth2ParameterNames.REQUEST_URI);
		if (StringUtils.hasText(requestUri)) {
			OAuth2PushedAuthorizationRequestUri pushedAuthorizationRequestUri;
			try {
				pushedAuthorizationRequestUri = OAuth2PushedAuthorizationRequestUri.parse(requestUri);
			}
			catch (Exception ex) {
				throw createException(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.REQUEST_URI,
						authorizationCodeRequestAuthentication, null);
			}

			pushedAuthorization = this.authorizationService.findByToken(pushedAuthorizationRequestUri.getState(),
					STATE_TOKEN_TYPE);
			if (pushedAuthorization == null) {
				throw createException(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.REQUEST_URI,
						authorizationCodeRequestAuthentication, null);
			}

			if (this.logger.isTraceEnabled()) {
				this.logger.trace("Retrieved authorization with pushed authorization request");
			}

			OAuth2AuthorizationRequest authorizationRequest = pushedAuthorization
				.getAttribute(OAuth2AuthorizationRequest.class.getName());
			Assert.notNull(authorizationRequest, "authorizationRequest cannot be null");

View on GitHub (pinned to 96852e8860)

Solutions

  1. Use the exact request_uri value returned in the PAR response (POST /oauth2/par), unmodified and correctly URL-encoded in the subsequent authorize redirect
  2. Check the value begins with urn:ietf:params:oauth:request_uri: and the base64url-encoded suffix is intact
  3. Regenerate the PAR request if the original value was altered or lost

Example fix

// before
https://auth.example.com/oauth2/authorize?client_id=x&request_uri=abc123
// after
https://auth.example.com/oauth2/authorize?client_id=x&request_uri=urn%3Aietf%3Aparams%3Aoauth%3Arequest_uri%3Ab64encodedValue
Defensive patterns

Strategy: validation

Validate before calling

if (requestUri == null || !requestUri.startsWith("urn:ietf:params:oauth:request_uri:")) {
    throw new IllegalArgumentException("malformed request_uri; use the value returned by the PAR endpoint verbatim");
}

Try / catch

try {
    HttpResponse<String> resp = send(authorizeRedirect);
} catch (OAuth2ErrorRedirectException | IOException ex) {
    if (ex.getMessage().contains("request_uri")) { /* re-run PAR and retry with fresh request_uri */ }
}

Prevention

When it happens

Trigger: An /oauth2/authorize GET request includes request_uri=<value>, but the value does not start with the PAR prefix 'urn:ietf:params:oauth:request_uri:' or its suffix does not decode to a valid, non-expired PAR structure (state + expiresAt).

Common situations: Clients copying the full request_uri including surrounding quotes or whitespace; sending a truncated URL; hand-rolled clients constructing the request_uri instead of using the value returned by the PAR endpoint; URL-encoding issues stripping characters.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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