spring-projects/spring-security · error · OAuth2AuthorizationCodeRequestAuthenticationException
invalid_request
invalid_request
Error message
OAuth 2.0 Parameter: redirect_uri
What it means
This error is thrown when validating the redirect_uri of an authorization code request and the URI is either missing entirely (when required) or contains a fragment component. OAuth2 forbids fragments in redirect URIs because fragments are never sent to the server, so the library rejects such requests with invalid_request attributed to redirect_uri.
Source
Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationValidator.java:134
RegisteredClient registeredClient = authenticationContext.getRegisteredClient();
String requestedRedirectUri = authorizationCodeRequestAuthentication.getRedirectUri();
if (StringUtils.hasText(requestedRedirectUri)) {
// ***** redirect_uri is available in authorization request
UriComponents requestedRedirect = null;
try {
requestedRedirect = UriComponentsBuilder.fromUriString(requestedRedirectUri).build();
}
catch (Exception ex) {
}
if (requestedRedirect == null || requestedRedirect.getFragment() != null) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(LogMessage.format("Invalid request: redirect_uri is missing or contains a fragment"
+ " for registered client '%s'", registeredClient.getId()));
}
throw createException(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.REDIRECT_URI,
authorizationCodeRequestAuthentication, registeredClient);
}
if (!isLoopbackAddress(requestedRedirect.getHost())) {
// As per
// https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-22#section-4.1.3
// When comparing client redirect URIs against pre-registered URIs,
// authorization servers MUST utilize exact string matching.
if (!registeredClient.getRedirectUris().contains(requestedRedirectUri)) {
throw createException(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.REDIRECT_URI,
authorizationCodeRequestAuthentication, registeredClient);
}
}
else {
// As per
// https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-08#section-8.4.2
// The authorization server MUST allow any port to be specified at the
// time of the request for loopback IP redirect URIs, to accommodateView on GitHub (pinned to 96852e8860)
Solutions
- Remove the fragment from the redirect_uri in the authorization request and from the registered redirect URIs.
- Always send redirect_uri explicitly and make sure it is a well-formed absolute URI with scheme, host, and path.
- For SPAs with hash routing, use path-based callback URLs (e.g. /callback) and route in the app after the redirect.
- Ensure the client has at least one registered redirect URI if redirect_uri is not provided in the request.
Example fix
// before String url = "/oauth2/authorize?response_type=code&client_id=my-client&redirect_uri=https://app.example.com/cb#home"; // after String url = "/oauth2/authorize?response_type=code&client_id=my-client&redirect_uri=https://app.example.com/cb";
Defensive patterns
Strategy: validation
Validate before calling
// validate the redirect_uri before sending the request
URI uri = URI.create(redirectUri);
boolean valid = uri.isAbsolute()
&& uri.getScheme() != null
&& uri.getHost() != null
&& uri.getFragment() == null;
if (!valid) {
throw new IllegalArgumentException("redirect_uri must be absolute with no fragment: " + redirectUri);
} Try / catch
try {
authenticate(authorizationRequest);
} catch (OAuth2AuthorizationCodeRequestAuthenticationException e) {
if ("invalid_request".equals(e.getError().getErrorCode())
&& "redirect_uri".equals(e.getError().getParameterName())) {
log.error("redirect_uri missing or contains a fragment: {}", authorizationRequest.getRedirectUri());
}
throw e;
} Prevention
- Never append fragments (#) to redirect URIs; SPAs should use path-based callbacks
- Always send redirect_uri explicitly rather than relying on a single registered default
- Validate redirect URIs in CI by parsing them with java.net.URI
- Keep registered redirect URIs fragment-free as well
When it happens
Trigger: OAuth2AuthorizationCodeRequestAuthenticationValidator.validateRedirectUri finds requestedRedirect == null (no valid redirect_uri could be resolved for the request) or requestedRedirect.getFragment() != null (e.g. redirect_uri=https://app.example.com/cb#section).
Common situations: Client omitted redirect_uri and the request is not using an exactly-one-registered-redirect-uri client; a frontend appends routing fragments (#/route) to the redirect URI; a registered or requested redirect URI copied from a SPA with hash-based routing; trailing whitespace/encoding issues causing URI parse failures.
Related errors
- Invalid Client Registration: + fieldName
- Invalid Client Registration: + fieldName
- OAuth 2.0 Parameter: + parameterName
- Invalid Client Registration: + fieldName
- invalid_request
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/ba3f1af6d811b27e.
Report an issue: GitHub.