Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R2DBC URL parser fails with "Illegal character in path" for specific URL patterns #34268

Open
anahi-gonzalez-clara opened this issue Jan 15, 2025 · 1 comment
Labels
status: waiting-for-triage An issue we've not yet triaged or decided on

Comments

@anahi-gonzalez-clara
Copy link

anahi-gonzalez-clara commented Jan 15, 2025

Description

The Spring R2DBC URL parser fails when handling certain database URLs, specifically throwing an "Illegal character in path at index 88" error. This appears to be related to URL length and character positioning, as shorter URLs with similar patterns work correctly.

Environment

  • Spring Boot: 3.3.1
  • Spring Framework: 6.1.10
  • Java: JDK 22

Steps to Reproduce

  1. Configure R2DBC with the following URL (FAILING URL):

r2dbc:postgresql://app-service-alpha-stg.abc123def456.sa-east-1.rds.amazonaws.com:37039/mydb1

  1. Start the application

Error Message

Caused by: java.lang.IllegalArgumentException: Illegal character in path at index 88: r2dbc://app-service-alpha-stg.abc123def456.sa-east-1.rds.amazonaws.com:37039/mydb1
at java.base/java.net.URI.create(URI.java:932)
at io.r2dbc.spi.ConnectionUrlParser.parseQuery(ConnectionUrlParser.java:93)
at io.r2dbc.spi.ConnectionFactoryOptions.parse(ConnectionFactoryOptions.java:138)

Expected Behavior

The URL should be parsed successfully, as it's a valid PostgreSQL connection URL that works with JDBC and can connect successfully using other tools like DBeaver.

Actual Behavior

The application fails to start with an IllegalArgumentException about an illegal character at index 88. However, important to note:

  1. The same exact URL works in DBeaver and other JDBC clients
  2. The database is accessible using this connection string
  3. Spring's R2DBC parser is the only component that fails to handle this URL

Interesting Observations

  1. Similar but shorter URLs work fine. For example (WORKING URL):
    r2dbc:postgresql://app-service-beta.xyz789uvw321.us-east-1.rds.amazonaws.com:37039/mydb1

  2. Key differences between working and failing URLs:

    • Failing URL is 99 characters long
    • Working URL is 95 characters
    • Failing URL has additional segments in hostname (-stg)
    • These differences cause different character positioning
  3. The error occurs specifically at index 88, where in the failing URL a '/' character is positioned

Workaround

The issue can be worked around by implementing a custom connection factory that bypasses Spring's URL parser:

@Configuration
class R2dbcConfig {
    @Value("${spring.r2dbc.url}")
    private String url;
    
    @Value("${spring.r2dbc.username}")
    private String username;
    
    @Value("${spring.r2dbc.password}")
    private String password;
    
    @Bean
    public ConnectionFactory connectionFactory() {
        String urlWithoutPrefix = url.replace("r2dbc:postgresql://", "");
        String[] parts = urlWithoutPrefix.split("/");
        String hostAndPort = parts[0];
        String database = parts[1].trim();
        
        String[] hostParts = hostAndPort.split(":");
        String host = hostParts[0];
        int port = Integer.parseInt(hostParts[1]);

        return new PostgresqlConnectionFactory(
            PostgresqlConnectionConfiguration.builder()
                .host(host)
                .port(port)
                .database(database)
                .username(username)
                .password(password)
                .build()
        );
    }
}
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jan 15, 2025
@quaff
Copy link
Contributor

quaff commented Jan 16, 2025

It's thrown by java.net.URI.create(), it may be caused by outdated JDK, you should test it against JDK directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting-for-triage An issue we've not yet triaged or decided on
Projects
None yet
Development

No branches or pull requests

3 participants