{"record":{"id":"79844814f345dd1a","repo":"apache/beam","slug":"invalid-jdbc-url-format","errorCode":null,"errorMessage":"Invalid JDBC URL format: ","messagePattern":"Invalid JDBC URL format: ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/clickhouse/src/main/java/org/apache/beam/sdk/io/clickhouse/ClickHouseJdbcUrlParser.java","lineNumber":111,"sourceCode":"    }\n\n    String actualUrl = extractHttpUrl(jdbcUrl);\n\n    try {\n      URI uri = new URI(actualUrl);\n\n      validateScheme(uri.getScheme());\n      String host = validateAndGetHost(uri.getHost(), jdbcUrl);\n      int port = getPortOrDefault(uri.getPort(), uri.getScheme());\n\n      String clickHouseUrl = String.format(\"%s://%s:%d\", uri.getScheme(), host, port);\n      String database = extractDatabase(uri.getPath());\n      Properties properties = extractProperties(uri.getQuery());\n\n      return new ParsedJdbcUrl(clickHouseUrl, database, properties);\n\n    } catch (URISyntaxException e) {\n      throw new IllegalArgumentException(\"Invalid JDBC URL format: \" + jdbcUrl, e);\n    } catch (java.io.UnsupportedEncodingException e) {\n      throw new IllegalArgumentException(\"Failed to decode URL parameters: \" + jdbcUrl, e);\n    }\n  }\n\n  /**\n   * Extracts and normalizes the HTTP/HTTPS URL from a JDBC URL.\n   *\n   * <p>Automatically detects HTTPS based on port 8443 or ssl=true parameter.\n   *\n   * @param jdbcUrl the JDBC URL to process\n   * @return normalized HTTP/HTTPS URL\n   * @throws IllegalArgumentException if the URL format is invalid\n   */\n  private static String extractHttpUrl(String jdbcUrl) {\n    // Remove jdbc: prefix\n    String urlWithoutJdbc = jdbcUrl;\n    if (jdbcUrl.toLowerCase().startsWith(\"jdbc:\")) {","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/clickhouse/src/main/java/org/apache/beam/sdk/io/clickhouse/ClickHouseJdbcUrlParser.java#L93-L129","documentation":"Thrown by ClickHouseJdbcUrlParser.parse when the JDBC URL cannot be syntactically parsed as a URI (the internal URISyntaxException is wrapped in an IllegalArgumentException). The message carries the original jdbcUrl so callers can see exactly which input was rejected.","triggerScenarios":"Calling parse() with a jdbc:clickhouse: URL whose authority, port, path or query violates URI syntax: unescaped spaces or special characters, a non-numeric port like host:abc, unbracketed IPv6 literals, or illegal characters in the database path/query.","commonSituations":"Building the URL by string concatenation from user input or env vars without URL-encoding; copy-pasted URLs with trailing whitespace or quotes; passwords or parameters containing reserved characters (?, #, %, spaces) placed raw in the query string.","solutions":["Inspect the jdbcUrl in the message and the wrapped URISyntaxException (getCause) for the exact invalid character/position.","URL-encode path and query components (URLEncoder.encode or the multi-argument URI constructor) before assembling the JDBC URL.","Strip whitespace/quotes from configuration values before passing them to parse().","Pass credentials containing special characters via a Properties object instead of the URL."],"exampleFix":"// before\nString url = \"jdbc:clickhouse://localhost:8123/default? user=default\"; // space in query -> URISyntaxException\n// after\nString url = \"jdbc:clickhouse://localhost:8123/default?user=\" + URLEncoder.encode(user, StandardCharsets.UTF_8);","handlingStrategy":"validation","validationCode":"boolean isValidJdbcUrl(String url) {\n  if (url == null || url.isBlank()) return false;\n  int schemeEnd = url.indexOf(':');\n  if (schemeEnd < 0 || !url.startsWith(\"jdbc:\")) return false;\n  try { new java.net.URI(url.substring(schemeEnd + 1)); return true; }\n  catch (java.net.URISyntaxException e) { return false; }\n}","typeGuard":"boolean hasRawSpecialChars(String url) {\n  return url != null && url.matches(\".*[\\\\s<>{}|\\\\\\\\^`].*\");\n}","tryCatchPattern":"try {\n  ParsedJdbcUrl parsed = ClickHouseJdbcUrlParser.parse(jdbcUrl);\n} catch (IllegalArgumentException e) {\n  LOG.error(\"Cannot parse JDBC URL {}: {}\", jdbcUrl,\n      e.getCause() != null ? e.getCause().getMessage() : e.getMessage());\n  throw new ConfigException(\"Malformed ClickHouse JDBC URL\", e);\n}","preventionTips":["Build URLs with the multi-argument URI constructor or URLEncoder for path/query parts.","Never embed raw credentials with special characters in the URL; use Properties.","Trim/strip whitespace and quotes from config values before constructing the URL.","Add a startup-time URL validation step with a clear error before the pipeline runs."],"tags":["jdbc","clickhouse","url-parsing","configuration"],"backgroundTag":"invalid-url-format","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}