{"record":{"id":"98abe9a78dba6578","repo":"spring-projects/spring-security","slug":"invalid-redirect-uri","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/authentication/OAuth2ClientRegistrationAuthenticationValidator.java","lineNumber":144,"sourceCode":"\n\tprivate static void validateRedirectUris(OAuth2ClientRegistrationAuthenticationContext authenticationContext) {\n\t\tOAuth2ClientRegistrationAuthenticationToken clientRegistrationAuthentication = authenticationContext\n\t\t\t.getAuthentication();\n\t\tList<String> redirectUris = clientRegistrationAuthentication.getClientRegistration().getRedirectUris();\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\n\t\t\t\t\t\t.debug(LogMessage.format(\"Invalid request: redirect_uri is not parseable ('%s')\", redirectUri));\n\t\t\t\t}\n\t\t\t\tthrow createException(OAuth2ErrorCodes.INVALID_REDIRECT_URI,\n\t\t\t\t\t\tOAuth2ClientMetadataClaimNames.REDIRECT_URIS);\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(\n\t\t\t\t\t\t\tLogMessage.format(\"Invalid request: redirect_uri contains a fragment ('%s')\", redirectUri));\n\t\t\t\t}\n\t\t\t\tthrow createException(OAuth2ErrorCodes.INVALID_REDIRECT_URI,\n\t\t\t\t\t\tOAuth2ClientMetadataClaimNames.REDIRECT_URIS);\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: redirect_uri has no scheme ('%s')\", redirectUri));\n\t\t\t\t}\n\t\t\t\tthrow createException(OAuth2ErrorCodes.INVALID_REDIRECT_URI,\n\t\t\t\t\t\tOAuth2ClientMetadataClaimNames.REDIRECT_URIS);\n\t\t\t}","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientRegistrationAuthenticationValidator.java#L126-L162","documentation":"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.","triggerScenarios":"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').","commonSituations":"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.","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"],"exampleFix":"// before\n{\"redirect_uris\": [\"/callback\"]}\n// after\n{\"redirect_uris\": [\"https://client.example.org/callback\"]}","handlingStrategy":"validation","validationCode":"try { new java.net.URI(redirectUri).toURL(); } catch (Exception e) { throw new IllegalArgumentException(\"redirect_uris entry is not a valid absolute URI: \" + redirectUri); }","typeGuard":"boolean isValidRedirectUri(String uri) {\n    try { return new java.net.URI(uri).isAbsolute(); } catch (Exception e) { return false; }\n}","tryCatchPattern":"catch (OAuth2ErrorResponseException e) { if (\"invalid_redirect_uri\".equals(e.getError().getErrorCode())) { log.error(\"Malformed redirect URI: {}\", e.getError().getParameters()); } }","preventionTips":["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"],"tags":["oauth2","client-registration","redirect-uri","url-validation"],"backgroundTag":"invalid-url-format","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}