{"record":{"id":"989bdd573575dcc2","repo":"apache/iceberg","slug":"failed-to-find-lock-for-table-s-s","errorCode":null,"errorMessage":"Failed to find lock for table %s.%s","messagePattern":"Failed to find lock for table (.+?)\\.(.+?)","errorType":"exception","errorClass":"LockException","httpStatus":null,"severity":"error","filePath":"hive-metastore/src/main/java/org/apache/iceberg/hive/MetastoreLock.java","lineNumber":323,"sourceCode":"                LockResponse lockResponse = metaClients.run(client -> client.lock(request));\n                lockInfo.lockId = lockResponse.getLockid();\n                lockInfo.lockState = lockResponse.getState();\n              } catch (TException te) {\n                LOG.warn(\"Failed to create lock {}\", request, te);\n                try {\n                  // If we can not check for lock, or we do not find it, then rethrow the exception\n                  // Otherwise we are happy as the findLock sets the lockId and the state correctly\n                  if (HiveVersion.min(HiveVersion.HIVE_2)) {\n                    LockInfo lockFound = findLock();\n                    if (lockFound != null) {\n                      lockInfo.lockId = lockFound.lockId;\n                      lockInfo.lockState = lockFound.lockState;\n                      LOG.info(\"Found lock {} by agentInfo {}\", lockInfo, agentInfo);\n                      return;\n                    }\n                  }\n\n                  throw new LockException(\n                      \"Failed to find lock for table %s.%s\", databaseName, tableName);\n                } catch (InterruptedException e) {\n                  Thread.currentThread().interrupt();\n                  interrupted.set(true);\n                  LOG.warn(\n                      \"Interrupted while trying to find lock for table {}.{}\",\n                      databaseName,\n                      tableName,\n                      e);\n                  throw new LockException(\n                      e,\n                      \"Interrupted while trying to find lock for table %s.%s\",\n                      databaseName,\n                      tableName);\n                }\n              } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n                interrupted.set(true);","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/hive-metastore/src/main/java/org/apache/iceberg/hive/MetastoreLock.java#L305-L341","documentation":"After creating the lock request, MetastoreLock polls ShowLocks results to find the lock it just created by matching agentInfo. If a poll iteration completes without finding the agent's own lock among the table's locks, this LockException is thrown. It means the lock created by this client vanished or was never visible in the metastore's lock listing.","triggerScenarios":"Calling commit on a Hive-catalog table when a showLocks poll no longer lists a lock whose agentInfo matches this client — e.g. the lock expired (hive.txn.timeout) and was purged between creation and the polling check, or another process aborted it.","commonSituations":"Very slow commits or GC pauses letting the lock expire mid-acquisition; multiple JVMs on the same host with colliding agentInfo and one unlocking the other's lock; metastore purging locks after a heartbeat failure.","solutions":["Increase hive.txn.timeout / lock heartbeat interval so short-lived locks are not purged during acquisition.","Ensure one JVM per host uses MetastoreLock, or that concurrent processes on the same host don't share/steal each other's locks (agentInfo collisions).","Re-run the commit; this is usually transient once the stale lock situation clears.","Check metastore logs for lock expiry/abortion events around the failure time to identify who removed the lock."],"exampleFix":"// before\nconf.setProperty(\"hive.txn.timeout\", \"60s\");\n// after\nconf.setProperty(\"hive.txn.timeout\", \"600s\"); // lock survives slow acquisition polls","handlingStrategy":"retry","validationCode":"// before committing, confirm the table's lock state via metastore:\n// ShowLocksResponse resp = client.showLocks(req);\n// abort if a foreign EXCLUSIVE lock already exists","typeGuard":null,"tryCatchPattern":"try {\n  table.commit(apply);\n} catch (LockException e) {\n  if (e.getMessage().startsWith(\"Failed to find lock\")) {\n    // transient lock loss; refresh and retry once metastore is stable\n    backoffRetry(() -> { table.refresh(); table.commit(apply); });\n  } else throw e;\n}","preventionTips":["Set hive.txn.timeout long enough that locks survive acquisition polling","Avoid multiple JVMs sharing a hostname that could steal each other's locks by agentInfo","Investigate metastore lock-purge logs if this recurs","Keep the acquisition loop fast; avoid long GC pauses during commit"],"tags":["hive","locking","concurrency","timeout"],"backgroundTag":"lock-not-found","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"}