{"record":{"id":"caf86ee0cd21e919","repo":"apache/iceberg","slug":"waiting-for-lock-on-table-s-s","errorCode":null,"errorMessage":"Waiting for lock on table %s.%s","messagePattern":"Waiting for lock on table (.+?)\\.(.+?)","errorType":"exception","errorClass":"WaitingForLockException","httpStatus":null,"severity":"warning","filePath":"hive-metastore/src/main/java/org/apache/iceberg/hive/MetastoreLock.java","lineNumber":216,"sourceCode":"        // upper bound of retries. So it is just reasonable to set a large retry count. However, if\n        // we set\n        // Integer.MAX_VALUE, the above logic of `retries + 1` would overflow into\n        // Integer.MIN_VALUE. Hence,\n        // the retry is set conservatively as `Integer.MAX_VALUE - 100` so it doesn't hit any\n        // boundary issues.\n        Tasks.foreach(lockInfo.lockId)\n            .retry(Integer.MAX_VALUE - 100)\n            .exponentialBackoff(lockCheckMinWaitTime, lockCheckMaxWaitTime, lockAcquireTimeout, 1.5)\n            .throwFailureWhenFinished()\n            .onlyRetryOn(WaitingForLockException.class)\n            .run(\n                id -> {\n                  try {\n                    LockResponse response = metaClients.run(client -> client.checkLock(id));\n                    LockState newState = response.getState();\n                    lockInfo.lockState = newState;\n                    if (newState.equals(LockState.WAITING)) {\n                      throw new WaitingForLockException(\n                          String.format(\n                              \"Waiting for lock on table %s.%s\", databaseName, tableName));\n                    }\n                  } catch (InterruptedException e) {\n                    Thread.interrupted(); // Clear the interrupt status flag\n                    LOG.warn(\n                        \"Interrupted while waiting for lock on table {}.{}\",\n                        databaseName,\n                        tableName,\n                        e);\n                  }\n                },\n                TException.class);\n      }\n    } catch (WaitingForLockException e) {\n      timeout = true;\n      duration = System.currentTimeMillis() - start;\n    } catch (TException e) {","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/hive-metastore/src/main/java/org/apache/iceberg/hive/MetastoreLock.java#L198-L234","documentation":"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.","triggerScenarios":"acquireLock's checkLock(id) returns LockState.WAITING during contention; long-running Hive transactions holding locks on the same table; multiple writers committing concurrently.","commonSituations":"Overlapping Spark/Flink jobs writing the same table; a stuck Hive transaction that never releases its lock; abnormally long commits holding the lock.","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."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  commit();\n} catch (CommitFailedException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Waiting for lock\")) {\n    // transient contention: back off and retry\n  }\n}","preventionTips":["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."],"tags":["hive","locking","contention","retry"],"backgroundTag":"request-timeout","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}