apache/iceberg · warning

Interrupted while waiting for lock on table

Error message

Interrupted while waiting for lock on table {}.{}

What it means

MetastoreLock.acquireLock() polls Hive's lock state in a loop, throwing WaitingForLockException on timeout and re-checking after backoff. If the polling thread is interrupted while sleeping/waiting, this warning is logged after clearing the interrupt flag, and the acquire loop continues waiting for the lock. It signals that a caller tried to interrupt a thread blocked waiting for a Hive table lock.

Solutions

  1. Find and release the contending Hive lock (SHOW LOCKS / unlock via Hive) so acquisition completes quickly.
  2. Investigate who interrupted the thread — typically job shutdown — and avoid interrupting during the commit critical section.
  3. Reduce lock hold times / tune lock acquisition timeouts so waits are short.
  4. Clean up stale locks left by crashed sessions (Hive LOCKS table maintenance).

Example fix

// before: interrupting the commit thread mid-lock-wait
commitThread.interrupt();
// after: cancel after the transaction completes
commitThread.join();
commitThread.interrupt();
Defensive patterns

Strategy: retry

Try / catch

try {
  lock.lock();
} catch (LockException | WaitingForLockException e) {
  // retry after releasing contending locks
}

Prevention

When it happens

Trigger: Thread calling MetastoreLock.lock() is interrupted while the acquireLock retry loop is sleeping between Hive lock checks (inside the Tasks.retry body's InterruptedException handler).

Common situations: Flink/executor shutdown interrupting worker threads; job cancellation while a commit is waiting on a contended Hive lock; lock held by a stale/abandoned session blocking another query for a long time.

Related errors


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

Appendix: source

Thrown at hive-metastore/src/main/java/org/apache/iceberg/hive/MetastoreLock.java:222

        Tasks.foreach(lockInfo.lockId)
            .retry(Integer.MAX_VALUE - 100)
            .exponentialBackoff(lockCheckMinWaitTime, lockCheckMaxWaitTime, lockAcquireTimeout, 1.5)
            .throwFailureWhenFinished()
            .onlyRetryOn(WaitingForLockException.class)
            .run(
                id -> {
                  try {
                    LockResponse response = metaClients.run(client -> client.checkLock(id));
                    LockState newState = response.getState();
                    lockInfo.lockState = newState;
                    if (newState.equals(LockState.WAITING)) {
                      throw new WaitingForLockException(
                          String.format(
                              "Waiting for lock on table %s.%s", databaseName, tableName));
                    }
                  } catch (InterruptedException e) {
                    Thread.interrupted(); // Clear the interrupt status flag
                    LOG.warn(
                        "Interrupted while waiting for lock on table {}.{}",
                        databaseName,
                        tableName,
                        e);
                  }
                },
                TException.class);
      }
    } catch (WaitingForLockException e) {
      timeout = true;
      duration = System.currentTimeMillis() - start;
    } catch (TException e) {
      thriftError = e;
    } finally {
      if (!lockInfo.lockState.equals(LockState.ACQUIRED)) {
        unlock(Optional.of(lockInfo.lockId));
      }
    }

View on GitHub (pinned to 86d9c8fc54)