apache/iceberg · error · UncheckedSQLException

Failed to check the state of the lock %s

Error message

Failed to check the state of the lock %s

What it means

JdbcLock.isHeld() throws UncheckedSQLException when the JDBC query against the lock table fails with a SQLException. The message includes the lock identity (%s = lock toString) so you can see which maintenance trigger lock could not be checked. This indicates a database-level problem rather than an interruption.

Source

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

    @Override
    public boolean isHeld() {
      try {
        return pool.run(
            conn -> {
              try (PreparedStatement sql = conn.prepareStatement(GET_LOCK_SQL)) {
                sql.setString(1, type.key);
                sql.setString(2, lockId);
                try (ResultSet rs = sql.executeQuery()) {
                  return rs.next();
                }
              }
            });
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new UncheckedInterruptedException(e, "Interrupted during isHeld");
      } catch (SQLException e) {
        // SQL exception happened when getting lock information
        throw new UncheckedSQLException(e, "Failed to check the state of the lock %s", this);
      }
    }

    @SuppressWarnings("checkstyle:NestedTryDepth")
    @Override
    public void unlock() {
      try {
        // Possible concurrency issue:
        // - `unlock` and `tryLock` happens at the same time when there is an existing lock
        //
        // Steps:
        // 1. `unlock` removes the lock in the database, but there is a temporary connection failure
        // 2. `lock` finds that there is no lock, so creates a new lock
        // 3. `unlock` retries the lock removal and removes the new lock
        //
        // To prevent the situation above we fetch the current lockId, and remove the lock
        // only with the given id.
        String instanceId = instanceId();

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Check database connectivity with the same JDBC URL/credentials and fix the underlying SQLException (see the wrapped cause).
  2. Verify the lock table exists and is accessible: run the catalog initialization / create the table manually if dropped.
  3. Enable connection pool validation (test-on-borrow / keepalive) to remove stale connections before queries.
  4. Grant the maintenance user SELECT/UPDATE privileges on the lock table.
  5. Retry the maintenance trigger after the database recovers; this error is usually transient.

Example fix

// before
String url = "jdbc:mysql://db:3306/iceberg"; // table missing -> SQLException
// after
// ensure lock table exists, e.g. run JdbcCatalog initializeCatalogObjects()
// or create: CREATE TABLE iceberg_locks (lock_id VARCHAR(255) PRIMARY KEY, ...);
String url = "jdbc:mysql://db:3306/iceberg?autoReconnect=true&socketTimeout=60000";
Defensive patterns

Strategy: retry

Validate before calling

// verify DB reachability before running maintenance
try (Connection c = DriverManager.getConnection(jdbcUrl, user, pass)) { if (!c.isValid(5)) throw new IllegalStateException("DB not reachable"); }

Try / catch

try { boolean held = lock.tryLock(); } catch (UncheckedSQLException e) { log.error("Lock check failed: {}", e.getCause(), e); /* alert + retry later */ }

Prevention

When it happens

Trigger: tryLock -> isHeld executes a SQL query on the lock table and the driver throws SQLException: bad connection, lock table missing, SQL syntax incompatibility, permissions, or database outage.

Common situations: Database restarted or connection pool evicted stale connections; lock table (created by JdbcCatalog) was dropped or the table name differs; using a database dialect with incompatible SQL; insufficient privileges for the maintenance user.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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