SonarSource/sonarqube · error · MessageException

Bad format of JDBC URL: %s

Error message

Bad format of JDBC URL: %s

What it means

JdbcSettings derives the database Provider from the JDBC URL by matching the pattern jdbc:(\w+):.+. If the URL does not match (missing sub-protocol or body), a MessageException 'Bad format of JDBC URL: <url>' is thrown. This is URL syntax validation before provider resolution.

Source

Thrown at server/sonar-main/src/main/java/org/sonar/application/config/JdbcSettings.java:119

    Integer embeddedDatabasePort = props.valueAsInt(JDBC_EMBEDDED_PORT.getKey());

    if (embeddedDatabasePort != null) {
      String correctUrl = buildH2JdbcUrl(embeddedDatabasePort);
      warnIfUrlIsSet(embeddedDatabasePort, url, correctUrl);
      props.set(JDBC_URL.getKey(), correctUrl);
      return Provider.H2;
    }

    if (isEmpty(url)) {
      props.set(JDBC_URL.getKey(), buildH2JdbcUrl(JDBC_EMBEDDED_PORT_DEFAULT_VALUE));
      props.set(JDBC_EMBEDDED_PORT.getKey(), String.valueOf(JDBC_EMBEDDED_PORT_DEFAULT_VALUE));
      return Provider.H2;
    }

    Pattern pattern = Pattern.compile("jdbc:(\\w+):.+");
    Matcher matcher = pattern.matcher(url);
    if (!matcher.find()) {
      throw new MessageException(format("Bad format of JDBC URL: %s", url));
    }
    String key = matcher.group(1);
    try {
      return Provider.valueOf(StringUtils.upperCase(key));
    } catch (IllegalArgumentException e) {
      throw new MessageException(format("Unsupported JDBC driver provider: %s", key));
    }
  }

  private static String buildH2JdbcUrl(int embeddedDatabasePort) {
    InetAddress ip = InetAddress.getLoopbackAddress();
    String host;
    if (ip instanceof Inet6Address) {
      host = "[" + ip.getHostAddress() + "]";
    } else {
      host = ip.getHostAddress();
    }
    return format("jdbc:h2:tcp://%s:%d/sonar%s", host, embeddedDatabasePort, IGNORED_KEYWORDS_OPTION);

View on GitHub (pinned to 184c821202)

Solutions

  1. Start the URL with 'jdbc:' followed by the database type, e.g. jdbc:postgresql://host:5432/sonar
  2. Ensure text follows the sub-protocol (the '.+' part of the pattern)
  3. Escape spaces/quotes in sonar.properties so the full URL reaches the parser
  4. Verify the property via server startup logs before restarting

Example fix

// before
sonar.jdbc.url=postgresql://localhost:5432/sonar
// after
sonar.jdbc.url=jdbc:postgresql://localhost:5432/sonar
Defensive patterns

Strategy: validation

Validate before calling

Pattern JDBC_URL = Pattern.compile("jdbc:(\\w+):.+");
if (url == null || !JDBC_URL.matcher(url).find()) throw new IllegalArgumentException("Not a valid JDBC URL: " + url);

Type guard

static boolean isValidJdbcUrl(String url) { return url != null && Pattern.matches("jdbc:\\w+:.+", url); }

Try / catch

try { jdbcSettings.start(); } catch (MessageException e) { if (e.getMessage().startsWith("Bad format of JDBC URL")) { fixUrlConfig(); } throw e; }

Prevention

When it happens

Trigger: Passing a sonar.jdbc.url that does not look like 'jdbc:<db>:<rest>', e.g. 'postgresql://localhost/sonar' (missing jdbc: prefix) or 'jdbc:' alone.

Common situations: Copying a connection-string format from a non-JDBC tool; forgetting the jdbc: prefix; truncating the URL during editing of sonar.properties; using env-var substitution that resolves to an empty/garbled value.

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 SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/5766e34b53e73cfa. Report an issue: GitHub.