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
- Wait — Iceberg retries automatically until acquisition or timeout; verify contention resolves.
- Find and kill the stuck Hive transaction (SHOW TRANSACTIONS / Abort Transaction) if it never releases.
- Reduce write concurrency to the table or partition writes to avoid overlap.
- 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
- Schedule writers so they don't overlap on the same table.
- Monitor SHOW LOCKS for stuck transactions and abort stale ones.
- Keep individual commits fast to reduce lock hold time.
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
- Timed out after %s ms waiting for lock on %s.%s
- Failed to acquire locks from metastore because the underlyin
- Lock is not active
- Failed to heartbeat for hive lock. %s
- Hive lock heartbeat thread not active
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/caf86ee0cd21e919.
Report an issue: GitHub.