{"record":{"id":"a31eacc6011bc78f","repo":"apache/druid","slug":"invalid-url-format-for-mysql-s","errorCode":null,"errorMessage":"Invalid URL format for MySQL: [%s]","messagePattern":"Invalid URL format for MySQL: \\[(.+?)\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/utils/ConnectionUriUtils.java","lineNumber":207,"sourceCode":"    Class<?> driverClass = Class.forName(POSTGRES_DRIVER);\n    Method parseUrl = driverClass.getMethod(\"parseURL\", String.class, Properties.class);\n    Properties properties = (Properties) parseUrl.invoke(null, connectionUri, null);\n    if (properties == null) {\n      throw new IAE(\"Invalid URL format for PostgreSQL: [%s]\", connectionUri);\n    }\n    Set<String> keys = Sets.newHashSetWithExpectedSize(properties.size());\n    properties.forEach((k, v) -> keys.add((String) k));\n    return keys;\n  }\n\n  public static Set<String> tryParseMySqlConnectionUri(String connectionUri)\n      throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException,\n             InvocationTargetException\n  {\n    Class<?> connectionUrlClass = Class.forName(MYSQL_CONNECTION_URL);\n    Method isConnectionStringSupported = connectionUrlClass.getMethod(\"acceptsUrl\", String.class);\n    if (!(boolean) isConnectionStringSupported.invoke(connectionUrlClass, connectionUri)) {\n      throw new IAE(\"Invalid URL format for MySQL: [%s]\", connectionUri);\n    }\n    Method getConnectionUrlInstanceMethod = connectionUrlClass.getMethod(\"getConnectionUrlInstance\", String.class, Properties.class);\n    Object conUrl = getConnectionUrlInstanceMethod.invoke(connectionUrlClass, connectionUri, null);\n    Method getHostsList = connectionUrlClass.getMethod(\"getHostsList\");\n    return getKeysFromOptions(getPropertiesFromHosts((List<?>) getHostsList.invoke(conUrl)));\n  }\n\n  private static Properties getPropertiesFromHosts(List<?> hostsList)\n      throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException\n  {\n    Properties properties = new Properties();\n    Class<?> hostInfoClass = Class.forName(MYSQL_HOST_INFO);\n    for (Object host : hostsList) {\n      Method getHostMethod = hostInfoClass.getMethod(\"getHost\");\n      String hostName = (String) getHostMethod.invoke(host);\n      if (hostName != null) {\n        properties.setProperty(\"HOST\", hostName);\n      }","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/utils/ConnectionUriUtils.java#L189-L225","documentation":"Thrown by ConnectionUriUtils.tryParseMySqlConnectionUri when the MySQL Connector/J ConnectionUrl class reports acceptsUrl(uri)==false for the given JDBC URI. Druid parses JDBC URIs reflectively to extract host/port/db properties (e.g. for extension metadata), and this check guards against URIs the MySQL driver cannot accept at all.","triggerScenarios":"Calling tryParseJdbcUriParameters (directly or via its callers) with a jdbc:mysql: URL that MySQL Connector/J rejects: wrong scheme spelling, missing '//' after jdbc:mysql:, unsupported MySQL X DevAPI forms, or a URI scheme routed to the MySQL parser that is not actually a mysql URL.","commonSituations":"Typos like 'jdbc:mysql//host:3306/db', copy-pasted URIs from other databases, dynamically built connection strings with empty or malformed host sections, or a mismatched mysql-connector-java version on the classpath that no longer accepts the URL shape.","solutions":["Verify the URI starts with jdbc:mysql:// and follows the documented Connector/J URL syntax","Confirm the intended MySQL Connector/J jar is on the classpath and matches the URL dialect","Log the full connectionUri and test it with a plain DriverManager.getConnection to see the driver's own complaint","If the URI belongs to another database, ensure it is routed to the correct parser, not the MySQL one"],"exampleFix":"// before\nString uri = \"jdbc:mysql//localhost:3306/druid\";\n// after\nString uri = \"jdbc:mysql://localhost:3306/druid\";","handlingStrategy":"try-catch","validationCode":"boolean valid = uri != null && uri.startsWith(\"jdbc:mysql://\");\nif (valid) {\n  try { java.sql.DriverManager.getConnection(uri + (uri.contains(\"?\") ? \"&\" : \"?\") + \"connectTimeout=1000\"); }\n  catch (Exception e) { /* driver rejects it */ }\n}","typeGuard":"static boolean looksLikeMySqlJdbcUri(String uri) {\n  return uri != null && uri.regionMatches(true, 0, \"jdbc:mysql://\", 0, 13);\n}","tryCatchPattern":"try {\n  params = ConnectionUriUtils.tryParseJdbcUriParameters(uri);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Invalid URL format for MySQL\")) {\n    log.error(\"Rejecting malformed MySQL URI: {}\", uri, e);\n  }\n  throw e;\n}","preventionTips":["Always build mysql URIs as jdbc:mysql://host:port/db?params","Test generated connection strings against DriverManager before persisting them","Keep the MySQL Connector/J version aligned with the URL dialect in use"],"tags":["jdbc","mysql","url-parsing"],"backgroundTag":"invalid-url-format","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}