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 accommodate

View on GitHub (pinned to 96852e8860)

Solutions

  1. Remove the fragment from the redirect_uri in the authorization request and from the registered redirect URIs.
  2. Always send redirect_uri explicitly and make sure it is a well-formed absolute URI with scheme, host, and path.
  3. For SPAs with hash routing, use path-based callback URLs (e.g. /callback) and route in the app after the redirect.
  4. 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

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


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