spring-projects/spring-security · error · OAuth2AuthenticationException
invalid_redirect_uri
invalid_redirect_uri
Error message
Invalid Client Registration: redirect_uris
What it means
During dynamic client registration, validateRedirectUris parses each registered redirect_uris value as a URI; when new URI(redirectUri) throws URISyntaxException the validator throws invalid_redirect_uri for the redirect_uris claim. The registration request is rejected because an unparseable redirect URI can never be validated safely in authorization flows.
Solutions
- Fix the offending redirect URI so it is a fully-qualified, syntactically valid absolute URI (scheme + host, properly percent-encoded)
- Check the debug log line 'Invalid request: redirect_uri is not parseable' to identify the exact malformed value
- Validate URIs client-side before submitting the registration request
Example fix
// before
{"redirect_uris": ["/callback"]}
// after
{"redirect_uris": ["https://client.example.org/callback"]} Defensive patterns
Strategy: validation
Validate before calling
try { new java.net.URI(redirectUri).toURL(); } catch (Exception e) { throw new IllegalArgumentException("redirect_uris entry is not a valid absolute URI: " + redirectUri); } Type guard
boolean isValidRedirectUri(String uri) {
try { return new java.net.URI(uri).isAbsolute(); } catch (Exception e) { return false; }
} Try / catch
catch (OAuth2ErrorResponseException e) { if ("invalid_redirect_uri".equals(e.getError().getErrorCode())) { log.error("Malformed redirect URI: {}", e.getError().getParameters()); } } Prevention
- Always register fully-qualified absolute URIs with scheme and host
- Percent-encode query parameters in redirect URIs
- Lint redirect URIs in CI before deploying registration payloads
- Avoid building URIs by naive string concatenation
When it happens
Trigger: POSTing a client-registration request whose redirect_uris array contains a string that is not a syntactically valid URI (e.g. missing scheme/host, illegal characters, spaces, or a relative path like '/callback').
Common situations: Copy-pasted URIs with typos or unencoded characters; forgetting 'https://' prefix; building URIs by string concatenation with unencoded query values; YAML/JSON config holding a bare path instead of an absolute URL.
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: + fieldName
- invalid_client_metadata
- invalid_client_metadata
- Invalid Client Registration: + fieldName
- Invalid Client Registration: + fieldName
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/98abe9a78dba6578.
Report an issue: GitHub.
Appendix: source
Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientRegistrationAuthenticationValidator.java:144
private static void validateRedirectUris(OAuth2ClientRegistrationAuthenticationContext authenticationContext) {
OAuth2ClientRegistrationAuthenticationToken clientRegistrationAuthentication = authenticationContext
.getAuthentication();
List<String> redirectUris = clientRegistrationAuthentication.getClientRegistration().getRedirectUris();
if (CollectionUtils.isEmpty(redirectUris)) {
return;
}
for (String redirectUri : redirectUris) {
URI parsed;
try {
parsed = new URI(redirectUri);
}
catch (URISyntaxException ex) {
if (LOGGER.isDebugEnabled()) {
LOGGER
.debug(LogMessage.format("Invalid request: redirect_uri is not parseable ('%s')", redirectUri));
}
throw createException(OAuth2ErrorCodes.INVALID_REDIRECT_URI,
OAuth2ClientMetadataClaimNames.REDIRECT_URIS);
}
if (parsed.getFragment() != null) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
LogMessage.format("Invalid request: redirect_uri contains a fragment ('%s')", redirectUri));
}
throw createException(OAuth2ErrorCodes.INVALID_REDIRECT_URI,
OAuth2ClientMetadataClaimNames.REDIRECT_URIS);
}
String scheme = parsed.getScheme();
if (scheme == null) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(LogMessage.format("Invalid request: redirect_uri has no scheme ('%s')", redirectUri));
}
throw createException(OAuth2ErrorCodes.INVALID_REDIRECT_URI,
OAuth2ClientMetadataClaimNames.REDIRECT_URIS);
}View on GitHub (pinned to 96852e8860)