apache/iceberg · info · UncheckedInterruptedException

Interrupted during unlock

Error message

Interrupted during unlock

What it means

Thrown by JdbcLock.unlock when the thread is interrupted while the DELETE (or lock-info read/update) that releases the maintenance lock is running. The interrupt flag is restored and the InterruptedException is wrapped in UncheckedInterruptedException. The lock release may not have completed — check the lock table state.

Source

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

              conn -> {
                try (PreparedStatement sql = conn.prepareStatement(DELETE_LOCK_SQL)) {
                  sql.setString(1, type.key);
                  sql.setString(2, lockId);
                  sql.setString(3, instanceId);
                  long count = sql.executeUpdate();
                  LOG.info(
                      "Deleted {} lock with instanceId {} with row count {}",
                      this,
                      instanceId,
                      count);
                }

                return null;
              });
        }
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new UncheckedInterruptedException(e, "Interrupted during unlock");
      } catch (SQLException e) {
        // SQL exception happened when getting/updating lock information
        throw new UncheckedSQLException(e, "Failed to remove lock %s", this);
      }
    }

    @Override
    public String toString() {
      return MoreObjects.toStringHelper(this).add("type", type).add("lockId", lockId).toString();
    }

    @SuppressWarnings("checkstyle:NestedTryDepth")
    private String instanceId() {
      try {
        return pool.run(
            conn -> {
              try (PreparedStatement sql = conn.prepareStatement(GET_LOCK_SQL)) {
                sql.setString(1, type.key);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Expected during cancellation, but verify afterwards that the lock row was deleted to avoid a stale lock
  2. If a stale lock remains, delete it manually from the lock table before the next maintenance run
  3. If unexpected, find the interrupt source and adjust task lifecycle/shutdown ordering
  4. Respect the restored interrupt flag in surrounding code

Example fix

// after catching during shutdown, clean up any stale lock
try {
  lock.unlock();
} catch (UncheckedInterruptedException e) {
  Thread.currentThread().interrupt();
  jdbcCleanup.deleteStaleLockRow(lockId); // avoid orphaned lock
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  lock.unlock();
} catch (UncheckedInterruptedException e) {
  Thread.currentThread().interrupt();
  // schedule a stale-lock sweep; release may not have completed
}

Prevention

When it happens

Trigger: unlock is called (normally when the maintenance task closes) and the thread is interrupted mid SQL execution — task cancellation or Flink failover during close().

Common situations: Flink cancels the job while close() releases the lock; shutdownNow on the executor during unlock; failover racing with lock release.

Related errors


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