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;
}
@OverrideView on GitHub (pinned to 86d9c8fc54)
Solutions
- Verify the JDBC URI in the JdbcLockFactory configuration points to an existing database and the driver is on the classpath
- Grant the configured DB user CREATE TABLE privileges in the target schema, or pre-create the lock tables manually
- Check the underlying SQLException (getCause) for the exact SQL error code and fix the table definition or name conflict
- 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
- Pre-create the lock tables with a privileged account and give the runtime user only DML rights
- Validate the JDBC URI and driver availability in deployment config tests
- Use a dedicated database/schema for maintenance locks to avoid name collisions
- Smoke-test lock factory creation in CI against the same DB engine as production
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
- Cannot initialize JDBC table maintenance lock
- Failed to check the state of the lock %s
- Failed to get lock information for %s
- Cannot initialize JDBC catalog
- Cannot check and eventually update SQL schema
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/2f68d401c27de522.
Report an issue: GitHub.