{"record":{"id":"e2b129aafdcaa0e4","repo":"spring-projects/spring-security","slug":"invalid-redirect-uri-e2b129","errorCode":"invalid_redirect_uri","errorMessage":"Invalid Client Registration: redirect_uris","messagePattern":"Invalid Client Registration: redirect_uris","errorType":"error_code","errorClass":"OAuth2AuthenticationException","httpStatus":null,"severity":"error","filePath":"oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationValidator.java","lineNumber":185,"sourceCode":"\t\tvalidateRedirectUrisStrict(postLogoutRedirectUris, \"invalid_client_metadata\",\n\t\t\t\tOidcClientMetadataClaimNames.POST_LOGOUT_REDIRECT_URIS);\n\t}\n\n\tprivate static void validateRedirectUrisStrict(List<String> redirectUris, String errorCode, String fieldName) {\n\t\tif (CollectionUtils.isEmpty(redirectUris)) {\n\t\t\treturn;\n\t\t}\n\t\tfor (String redirectUri : redirectUris) {\n\t\t\tURI parsed;\n\t\t\ttry {\n\t\t\t\tparsed = new URI(redirectUri);\n\t\t\t}\n\t\t\tcatch (URISyntaxException ex) {\n\t\t\t\tif (LOGGER.isDebugEnabled()) {\n\t\t\t\t\tLOGGER.debug(\n\t\t\t\t\t\t\tLogMessage.format(\"Invalid request: %s is not parseable ('%s')\", fieldName, redirectUri));\n\t\t\t\t}\n\t\t\t\tthrow createException(errorCode, fieldName);\n\t\t\t}\n\t\t\tif (parsed.getFragment() != null) {\n\t\t\t\tif (LOGGER.isDebugEnabled()) {\n\t\t\t\t\tLOGGER.debug(LogMessage.format(\"Invalid request: %s contains a fragment ('%s')\", fieldName,\n\t\t\t\t\t\t\tredirectUri));\n\t\t\t\t}\n\t\t\t\tthrow createException(errorCode, fieldName);\n\t\t\t}\n\t\t\tString scheme = parsed.getScheme();\n\t\t\tif (scheme == null) {\n\t\t\t\tif (LOGGER.isDebugEnabled()) {\n\t\t\t\t\tLOGGER.debug(LogMessage.format(\"Invalid request: %s has no scheme ('%s')\", fieldName, redirectUri));\n\t\t\t\t}\n\t\t\t\tthrow createException(errorCode, fieldName);\n\t\t\t}\n\t\t\tif (isUnsafeScheme(scheme)) {\n\t\t\t\tif (LOGGER.isDebugEnabled()) {\n\t\t\t\t\tLOGGER.debug(","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationValidator.java#L167-L203","documentation":"During OIDC client registration (dynamic registration) the validator strictly checks each redirect URI (or post-logout redirect URI): it must be parseable as a URI. If new URI(redirectUri) throws URISyntaxException, registration is rejected with an invalid_redirect_uri error for field 'redirect_uris'.","triggerScenarios":"POST to the client registration endpoint with a redirect_uris (or post_logout_redirect_uris) entry that is not a syntactically valid URI, e.g. 'http://exa mple.com/cb' or missing entirely malformed string.","commonSituations":"Unencoded spaces or special characters in the URI; truncation when copying from docs; scheme-less fragments like 'localhost:8080/cb' mishandled; multi-value field mis-split producing garbage entries.","solutions":["URL-encode all query parameters and path segments in each redirect URI and re-submit the registration request","Ensure each URI parses: new URI(uri) in a pre-check before calling the registration endpoint","Check the client sends each redirect URI as a separate array element, not a space-separated string"],"exampleFix":"// before\n\"redirect_uris\": [\"https://example.com/cb?next=/a b\"]\n// after\n\"redirect_uris\": [\"https://example.com/cb?next=%2Fa%20b\"]","handlingStrategy":"validation","validationCode":"for (String uri : redirectUris) {\n    try { new URI(uri); }\n    catch (URISyntaxException e) { throw new IllegalArgumentException(\"unparseable redirect_uri: \" + uri); }\n}","typeGuard":null,"tryCatchPattern":"try {\n    clientRegistrationService.save(newRegistration);\n} catch (OAuth2AuthenticationException ex) {\n    // errorCode invalid_redirect_uri, description names redirect_uris\n}","preventionTips":["Percent-encode query/path components in redirect URIs","Validate every URI client-side before submitting registration","Keep each URI a distinct JSON array element"],"tags":["oauth2","oidc","url","validation"],"backgroundTag":"invalid-redirect-uri","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}