apache/seatunnel · error · OptionValidationException

Invalid JDBC URL format: [%s], expected pattern: jdbc:<schem

Error message

Invalid JDBC URL format: [%s], expected pattern: jdbc:<scheme>://host:port[/database]

What it means

JdbcCommonOptions URL validation parses every generic JDBC url with JdbcUrlUtil.getUrlInfo and requires the form jdbc:<scheme>://host:port[/database]. When parsing fails it throws an OptionValidationException with the generic pattern message. This is a startup-time sanity check for the connector's url option.

Source

Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/config/JdbcCommonOptions.java:215

     * is optional to maintain backward compatibility with connectors (e.g. StarRocks, Doris) that
     * specify the database in the query or table_path instead of the URL.
     */
    public static class UrlContainsDatabaseValidator implements ConditionExtension<String> {
        @Override
        public String description() {
            return "JDBC URL must be a valid format: jdbc:<scheme>://host:port[/database]";
        }

        @Override
        public boolean evaluate(ReadonlyConfig config, String url) {
            if (url == null || url.trim().isEmpty()) {
                return false;
            }
            try {
                JdbcUrlUtil.UrlInfo urlInfo = JdbcUrlUtil.getUrlInfo(url);
                return StringUtils.isNotBlank(urlInfo.getHost());
            } catch (IllegalArgumentException e) {
                throw new OptionValidationException(
                        String.format(
                                "Invalid JDBC URL format: [%s], "
                                        + "expected pattern: jdbc:<scheme>://host:port[/database]",
                                url));
            }
        }
    }
}

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Rewrite the URL as jdbc:<scheme>://host:port[/database], e.g. jdbc:mysql://localhost:3306/mydb
  2. Check the scheme portion is present and the host is non-blank after //
  3. Replace unresolved placeholders (${...}) with actual values in the rendered config
  4. If your database genuinely requires a non-host URL form, verify the connector variant supports it

Example fix

// before
String url = "jdbc:mysql://localhost/mydb"; // missing port is OK, but placeholder breaks parse
String url = "jdbc:mysql://${DB_HOST}:3306/mydb";
// after
String url = "jdbc:mysql://10.0.0.5:3306/mydb";
Defensive patterns

Strategy: validation

Validate before calling

String url = (String) options.get("url");
if (url == null || !url.matches("jdbc:[a-z0-9]+://[^:/\\s]+:\\d+.*")) {
    throw new IllegalArgumentException("url must be jdbc:<scheme>://host:port[/database]");
}

Type guard

static boolean isValidJdbcUrl(String url) {
    return url != null && url.startsWith("jdbc:") && url.contains("://")
        && !url.substring(url.indexOf("://") + 3).isBlank();
}

Try / catch

try {
    JdbcCommonOptions.validateUrl(url);
} catch (OptionValidationException e) {
    throw new IllegalArgumentException("Fix 'url' option: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Passing a url that is blank, uses a non-host based form (e.g. jdbc:sqlite:/path/file.db or service-name TNS strings), omits //host:port, or is otherwise rejected by JdbcUrlUtil.getUrlInfo.

Common situations: Using file-style URLs (H2, SQLite) with the generic option, forgetting the port, URL built by string concatenation that lost the scheme, environment-specific placeholders left unsubstituted (e.g. ${DB_HOST}).

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


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/758840720b2a72c3. Report an issue: GitHub.