SonarSource/sonarqube · critical · java.lang.IllegalArgumentException

Unsupported dialect id

Error message

Unsupported dialect id 

What it means

During the 202605.00 migration, CreateIndexOnIssuesDeferralDate creates an index on ISSUES.DEFERAL_DATE. Oracle (and H2) get a plain single-column index, while PostgreSQL/MySQL/MSSQL get a partial index that also filters on status and project_uuid. If the current dialect matches none of the handled cases, createIndex throws this IllegalArgumentException to abort the migration rather than create a subtly wrong index.

Source

Thrown at server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202605/CreateIndexOnIssuesDeferralDate.java:66

    }
  }

  private void createIndex(Context context, Connection connection) {
    if (DatabaseUtils.indexExistsIgnoreCase(TABLE_NAME, INDEX_NAME, connection)) {
      return;
    }
    switch (getDialect().getId()) {
      // Partial index: only rows with a pending deferral are stored, so INCLUDE columns stay cheap.
      case PostgreSql.ID, MsSql.ID -> context.execute(
        format("CREATE INDEX %s ON %s (%s) INCLUDE (%s) WHERE %s IS NOT NULL",
          INDEX_NAME, TABLE_NAME, COLUMN_NAME, INCLUDE_COLUMNS, COLUMN_NAME));
      // Oracle B-tree omits rows where all indexed columns are NULL, so a plain single-column
      // index is already partial there. Do not add status/project_uuid as key columns - that would
      // make every row non-NULL again and defeat it. H2 does index NULL keys, so the index is not
      // partial there; H2 is only used for tests and the schema dump, so that is acceptable.
      case Oracle.ID, H2.ID -> context.execute(
        format("CREATE INDEX %s ON %s (%s)", INDEX_NAME, TABLE_NAME, COLUMN_NAME));
      default -> throw new IllegalArgumentException("Unsupported dialect id " + getDialect().getId());
    }
  }
}

View on GitHub (pinned to 184c821202)

Solutions

  1. Check sonar.jdbc.url and switch to a supported database (PostgreSQL, MySQL, MSSQL, Oracle).
  2. Verify the JDBC driver jar matches the declared URL scheme so the correct dialect is detected.
  3. If on a custom/newer dialect, update the migration's switch to handle its Dialect.ID with an appropriate partial/plain index.
  4. Report the issue to SonarSource if a supported database is correctly configured and still hits this path.

Example fix

// before
default -> throw new IllegalArgumentException("Unsupported dialect id " + getDialect().getId());
// after
// configure a supported database
sonar.jdbc.url=jdbc:postgresql://localhost/sonar
Defensive patterns

Strategy: validation

Validate before calling

String url = props.get("sonar.jdbc.url");
Set<String> supported = Set.of("postgresql", "mysql", "mssql", "oracle", "h2");
if (supported.stream().noneMatch(url.toLowerCase()::contains)) {
    throw new IllegalArgumentException("Unsupported sonar.jdbc.url: " + url);
}

Try / catch

try { migration.execute(context); } catch (IllegalArgumentException e) { log.severe("Migration aborted: " + e.getMessage()); throw e; }

Prevention

When it happens

Trigger: Running a SonarQube server startup DB migration against a JDBC dialect whose id is not Oracle, H2, PostgreSQL, MySQL, or MSSQL — i.e. getDialect().getId() returns an unknown value when execute() invokes createIndex().

Common situations: Pointing sonar.jdbc.url at an unsupported or custom JDBC driver/dialect (e.g. an experimental fork, a mistyped URL string that maps to no known dialect), or running a bleeding-edge server build on a newly added dialect whose migration code has not been updated yet.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/9e3dba2c856de0ba. Report an issue: GitHub.