apache/iceberg · error · UncheckedSQLException

Cannot initialize JDBC table maintenance lock

Error message

Cannot initialize JDBC table maintenance lock

What it means

Thrown by JdbcLockFactory.initializeLockTables (called from open) when the DDL statements that create the maintenance lock tables fail with a generic SQLException. The lock-table initialization (CREATE TABLE for the trigger lock tables) could not be completed against the configured JDBC database. This is the catch-all branch after timeout and connection-failure cases have been handled separately.

Source

Thrown at flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/JdbcLockFactory.java:155

                LOG.debug("Flink maintenance lock table already exists");
                return true;
              }
            }
            LOG.info("Creating Flink maintenance lock table {}", LOCK_TABLE_NAME);
            try (PreparedStatement ps = conn.prepareStatement(CREATE_LOCK_TABLE_SQL)) {
              ps.execute();
            }

            return true;
          });
    } catch (SQLTimeoutException e) {
      throw new UncheckedSQLException(
          e, "Cannot initialize JDBC table maintenance lock: Query timed out");
    } catch (SQLTransientConnectionException | SQLNonTransientConnectionException e) {
      throw new UncheckedSQLException(
          e, "Cannot initialize JDBC table maintenance lock: Connection failed");
    } catch (SQLException e) {
      throw new UncheckedSQLException(e, "Cannot initialize JDBC table maintenance lock");
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      throw new UncheckedInterruptedException(e, "Interrupted in call to initialize");
    }
  }

  private static class JdbcLock implements TriggerLockFactory.Lock {
    private final JdbcClientPool pool;
    private final String lockId;
    private final Type type;

    private JdbcLock(JdbcClientPool pool, String lockId, Type type) {
      this.pool = pool;
      this.lockId = lockId;
      this.type = type;
    }

    @Override

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Verify the JDBC URI in the JdbcLockFactory configuration points to an existing database and the driver is on the classpath
  2. Grant the configured DB user CREATE TABLE privileges in the target schema, or pre-create the lock tables manually
  3. Check the underlying SQLException (getCause) for the exact SQL error code and fix the table definition or name conflict
  4. Drop leftover/corrupt lock tables from a previous failed initialization and retry

Example fix

// before
TableMaintenance.forTable(table)
    .lockFactory(JdbcLockFactory.builder()
        .jdbcUrl("jdbc:postgresql://db:5432/missing_db")
        ...) // fails: database missing_db does not exist
// after
TableMaintenance.forTable(table)
    .lockFactory(JdbcLockFactory.builder()
        .jdbcUrl("jdbc:postgresql://db:5432/iceberg")
        ...) // database exists, user has CREATE privilege
Defensive patterns

Strategy: validation

Validate before calling

// before configuring JdbcLockFactory, verify DB access
try (Connection c = DriverManager.getConnection(jdbcUrl, user, pass)) {
  DatabaseMetaData md = c.getMetaData();
  boolean canCreate = !c.getMetaData().getTables(null, null, lockTableName + "%", new String[]{"TABLE"}).next()
      || c.createStatement().executeQuery("SELECT 1").next(); // connection ok
} catch (SQLException e) { throw new IllegalStateException("Lock DB unreachable: " + e.getMessage()); }

Prevention

When it happens

Trigger: Calling JdbcLockFactory.create/open where the CREATE TABLE for the lock tables fails: the configured user lacks CREATE privileges, the lock table name collides with an existing incompatible table, the database/schema does not exist, or the JDBC URL points to a non-existent database.

Common situations: Misconfigured lock-table JdbcCatalog URI in the maintenance TableMaintenance builder; deploying to an environment where the DB user is read-only; switching databases (e.g. from Postgres to MySQL) without pre-creating the schema; a partially-created lock table left over from a failed prior run.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/2f68d401c27de522. Report an issue: GitHub.