apache/iceberg · error · UncheckedSQLException

Cannot initialize JDBC table maintenance lock: Query timed…

Error message

Cannot initialize JDBC table maintenance lock: Query timed out

What it means

JdbcLockFactory.initializeLockTables creates the maintenance-lock tables via JdbcClientPool within a configured query timeout. If the SQL statement raises SQLTimeoutException (the query timed out), the factory wraps it in UncheckedSQLException with this message. It means the database did not respond in time while setting up lock tables.

Solutions

  1. Check the database for blocking transactions/DDL locks (e.g. pg_locks / information_schema.innodb_trx) and resolve them.
  2. Increase the lock-table acquisition timeout (uriTimeout/timeout in the JdbcLockFactory builder or JDBC URL connect/statement timeout settings).
  3. Verify DB connectivity and health; retry initialization once the database is responsive.
  4. Ensure the lock tables are created up-front (run schema creation manually) so runtime DDL doesn't need to wait.

Example fix

// before
JdbcLockFactory.createLockFactory("jdbc:postgresql://db:5432/app", "user", "pass", 5)
// after
JdbcLockFactory.createLockFactory("jdbc:postgresql://db:5432/app", "user", "pass", 60)
Defensive patterns

Strategy: retry

Validate before calling

// preflight: verify the DB accepts DDL within a few seconds
try (Connection c = DriverManager.getConnection(uri, user, pass)) {
  c.setLoginTimeout(5);
  c.isValid(5);
}

Try / catch

try {
  TriggerLockFactory f = JdbcLockFactory.createLockFactory(uri, user, pass, timeoutSeconds);
  f.open();
} catch (UncheckedSQLException e) {
  if (e.getCause() instanceof SQLTimeoutException) {
    // backoff and retry with a larger timeout
  } else throw e;
}

Prevention

When it happens

Trigger: JdbcLockFactory.create/open -> initializeLockTables executing CREATE TABLE (or equivalent) for the lock tables when the JDBC driver reports a statement timeout (lock-table DDL blocked by an existing lock or a hung database).

Common situations: Slow or overloaded database, DDL waiting on a metadata lock held by another transaction, network latency to a remote DB, or an aggressively small lock.table timeout configured via JdbcLockFactory builder.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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

Appendix: source

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

                dbMeta.getTables(
                    null /* catalog name */,
                    null /* schemaPattern */,
                    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) {

View on GitHub (pinned to 86d9c8fc54)