apache/iceberg · critical · UncheckedSQLException
Cannot initialize JDBC table maintenance lock: Connection…
Error message
Cannot initialize JDBC table maintenance lock: Connection failed
What it means
During JdbcLockFactory initialization the SQL operation raised SQLTransientConnectionException or SQLNonTransientConnectionException, meaning the database connection could not be established or failed. It is wrapped as UncheckedSQLException with this message.
Solutions
- Verify the JDBC URL, host, port and credentials are correct and the database is reachable (test with psql/mysql client).
- Check DB server logs and network/firewall rules; restart or failover the DB if it is down.
- Retry initialization — transient connection exceptions may clear on their own.
- Confirm connection pool sizing isn't exhausting connections shared with other jobs.
Example fix
// before lockFactory uri: jdbc:postgresql://wrong-host:5432/app // after lockFactory uri: jdbc:postgresql://db-primary.internal:5432/app
Defensive patterns
Strategy: retry
Validate before calling
// preflight connectivity check before creating the lock factory Connection c = DriverManager.getConnection(uri, user, pass); // throws SQLException if unreachable c.close();
Try / catch
try {
lockFactory.open();
} catch (UncheckedSQLException e) {
if (e.getCause() instanceof SQLTransientConnectionException) {
// retry with backoff; transient failures often self-heal
} else throw e;
} Prevention
- Validate JDBC URL/credentials with a client before deploying
- Ensure network/firewall allows Flink workers to reach the DB
- Use a highly available DB endpoint
- Watch connection-pool saturation metrics
When it happens
Trigger: JdbcLockFactory.create/open -> initializeLockTables when the driver reports a transient (e.g. pool/connection acquisition) or non-transient connection failure while creating/verifying the lock tables.
Common situations: Wrong JDBC host/port, DB restarted or in recovery, connection pool exhausted, firewall/network interruption, or invalid credentials rejected with a connection-class exception.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- Cannot initialize JDBC table maintenance lock
- Cannot initialize JDBC table maintenance lock: Query timed…
- Failed to check the state of the lock
- Failed to create lock
- Failed to get lock information for
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/10b78b49e15157ee.
Report an issue: GitHub.
Appendix: source
Thrown at flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/JdbcLockFactory.java:152
LOCK_TABLE_NAME /* tableNamePattern */,
null /* types */)) {
if (rs.next()) {
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;View on GitHub (pinned to 86d9c8fc54)