apache/iceberg · warning · WaitingForLockException

Waiting for lock on table %s.%s

Error message

Waiting for lock on table %s.%s

What it means

While waiting to acquire a Hive lock, checkLock reported state WAITING, meaning another transaction/client holds the lock on the table. Iceberg uses this as a retry signal (WaitingForLockException) and keeps polling until the lock is acquired or the timeout expires.

Source

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

        // upper bound of retries. So it is just reasonable to set a large retry count. However, if
        // we set
        // Integer.MAX_VALUE, the above logic of `retries + 1` would overflow into
        // Integer.MIN_VALUE. Hence,
        // the retry is set conservatively as `Integer.MAX_VALUE - 100` so it doesn't hit any
        // boundary issues.
        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) {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Wait — Iceberg retries automatically until acquisition or timeout; verify contention resolves.
  2. Find and kill the stuck Hive transaction (SHOW TRANSACTIONS / Abort Transaction) if it never releases.
  3. Reduce write concurrency to the table or partition writes to avoid overlap.
  4. Increase the lock acquisition timeout in Iceberg's lock configuration if waits are expected.
Defensive patterns

Strategy: retry

Try / catch

try {
  commit();
} catch (CommitFailedException e) {
  if (e.getMessage() != null && e.getMessage().contains("Waiting for lock")) {
    // transient contention: back off and retry
  }
}

Prevention

When it happens

Trigger: acquireLock's checkLock(id) returns LockState.WAITING during contention; long-running Hive transactions holding locks on the same table; multiple writers committing concurrently.

Common situations: Overlapping Spark/Flink jobs writing the same table; a stuck Hive transaction that never releases its lock; abnormally long commits holding the lock.

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/caf86ee0cd21e919. Report an issue: GitHub.