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
- Use the exact request_uri value returned in the PAR response (POST /oauth2/par), unmodified and correctly URL-encoded in the subsequent authorize redirect
- Check the value begins with urn:ietf:params:oauth:request_uri: and the base64url-encoded suffix is intact
- 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
- Pass the PAR response's request_uri through unchanged and correctly URL-encoded in the authorize redirect
- Do not reconstruct or trim the request_uri string by hand
- Add a client-side smoke test that runs the full PAR -> authorize flow
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
- Invalid Client Registration with Id: ${registrationId}
- Authorization Request failed: %s
- Removed expired pushed authorization request for client id '
- invalid_scope
- Unable to create an {OAuth2AuthorizedClientManager} bean. Ex
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/f8ba199ee2da7815.
Report an issue: GitHub.