apache/beam · error · SQLException

Unexpected null when creating synthetic Beam JdbcDriver

Error message

Unexpected null when creating synthetic Beam JdbcDriver

What it means

JdbcDriver.getConnection creates a synthetic JdbcConnection by calling the driver's connect() with a deliberately bogus URL; Calcite's connect may legally return null for unsuitable URLs, but here the URL is fixed and known-good, so a null indicates an internal driver state problem. The method throws SQLException (which the caller wraps in RuntimeException) to fail fast rather than NPE later.

Source

Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/JdbcDriver.java:188

  private static JdbcConnection getConnection(PipelineOptions options) {
    Properties properties = new Properties();
    properties.setProperty(
        SCHEMA_FACTORY.camelName(), BeamCalciteSchemaFactory.Empty.class.getName());
    BeamSqlPipelineOptions sqlOptions = options.as(BeamSqlPipelineOptions.class);
    if (sqlOptions != null) {
      Map<String, String> calciteConnectionProperties = sqlOptions.getCalciteConnectionProperties();
      if (calciteConnectionProperties != null) {
        properties.putAll(calciteConnectionProperties);
      }
    }
    JdbcConnection connection;
    try {
      connection = (JdbcConnection) INSTANCE.connect(CONNECT_STRING_PREFIX, properties);
      // Normally, #connect is allowed to return null when the URL is not suitable. Here, however,
      // we are
      // deliberately passing a bogus URL to instantiate a connection, so it should never be null.
      if (connection == null) {
        throw new SQLException("Unexpected null when creating synthetic Beam JdbcDriver");
      }
    } catch (SQLException e) {
      throw new RuntimeException(e);
    }
    connection.setPipelineOptions(options);
    return connection;
  }
}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Check the classpath for conflicting Calcite versions (mvn dependency:tree) and pin a single calcite-core version matching Beam's SQL module.
  2. Verify the Beam JdbcDriver is the driver handling the internal CONNECT_STRING_PREFIX and is not shadowed by another driver registered earlier.
  3. If you hit this without modifying Beam internals, report/inspect for a shading or dependency-injection issue in your build.
  4. Catch the resulting RuntimeException from connection() and surface a clear classpath-diagnosis message to users.

Example fix

// before (caller of JdbcDriver.connection(options))
JdbcConnection conn = JdbcDriver.connection(options);
// after
try {
  JdbcConnection conn = JdbcDriver.connection(options);
} catch (RuntimeException e) {
  throw new IllegalStateException(
      "Beam JDBC synthetic connection failed; check for duplicate calcite versions on the classpath", e);
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  JdbcConnection conn = JdbcDriver.connection(options);
} catch (RuntimeException e) {
  throw new IllegalStateException("Beam synthetic JDBC connection failed; check calcite classpath", e);
}

Prevention

When it happens

Trigger: Calling JdbcDriver.getConnection(pipelineOptions) (from the connection() factory) when Calcite's JdbcDriver.connect returns null for the internal CONNECT_STRING_PREFIX — typically a broken/changed Calcite driver registration or incompatible calcite JDBC version on the classpath.

Common situations: Classpath conflicts where another JDBC driver or a different Calcite version claims/handles the 'jdbc:beam:' prefix; shading that drops the driver registration; calcite-core version skew after dependency upgrades.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/3728d98b13f96346. Report an issue: GitHub.