{"record":{"id":"4a8c1e38de87a377","repo":"apache/iceberg","slug":"unable-to-acquire-lock","errorCode":null,"errorMessage":"Unable to acquire lock ","messagePattern":"Unable to acquire lock ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/util/LockManagers.java","lineNumber":234,"sourceCode":"            scheduler()\n                .scheduleAtFixedRate(\n                    () -> {\n                      InMemoryLockContent lastContent = LOCKS.get(entityId);\n                      try {\n                        long newExpiration = System.currentTimeMillis() + heartbeatTimeoutMs();\n                        LOCKS.replace(\n                            entityId, lastContent, new InMemoryLockContent(ownerId, newExpiration));\n                      } catch (NullPointerException e) {\n                        throw new RuntimeException(\n                            \"Cannot heartbeat to a deleted lock \" + entityId, e);\n                      }\n                    },\n                    0,\n                    heartbeatIntervalMs(),\n                    TimeUnit.MILLISECONDS));\n\n      } else {\n        throw new IllegalStateException(\"Unable to acquire lock \" + entityId);\n      }\n    }\n\n    @Override\n    public boolean acquire(String entityId, String ownerId) {\n      try {\n        Tasks.foreach(entityId)\n            .retry(Integer.MAX_VALUE - 1)\n            .onlyRetryOn(IllegalStateException.class)\n            .throwFailureWhenFinished()\n            .exponentialBackoff(acquireIntervalMs(), acquireIntervalMs(), acquireTimeoutMs(), 1)\n            .run(id -> acquireOnce(id, ownerId));\n        return true;\n      } catch (IllegalStateException e) {\n        return false;\n      }\n    }\n","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/util/LockManagers.java#L216-L252","documentation":"LockManagers' base implementation throws this IllegalStateException when a lock acquisition attempt never succeeds within the retry/timeout budget but no acquire callback ever returned true. It signals the caller could not become the lock owner for the given entityId, so the protected operation must not proceed.","triggerScenarios":"Calling acquire(entityId, ownerId) (via acquireOnce) on a lock manager whose underlying acquire call keeps failing or timing out — e.g. Hive/InMemory lock contention, wrong lock table configuration, or a stuck heartbeat.","commonSituations":"Two concurrent Spark/Flink jobs committing to the same table with a misconfigured Hive metastore lock; expired heartbeat threads; lock manager pointing at an unreachable metastore.","solutions":["Check the lock manager configuration (type, heartbeat interval, timeouts) and correct it","Verify no other process holds the lock for the same entityId; release stale locks","Increase acquire timeout/heartbeat intervals in the table properties","Use a different LockManager implementation suited to your catalog"],"exampleFix":"// before\nTableMetadata locked = commitWithLock(table); // fails when lock not acquired\n// after\nlong timeoutMs = 300_000;\ntry (LockManager lock = LockManagers.from(properties)) {\n  lock.acquire(\"table-id\", \"owner-1\"); // with larger acquire-timeout-ms property\n}","handlingStrategy":"retry","validationCode":"// before acquiring\nif (!lockManagerProperties.containsKey(\"acquire.timeout-ms\") ||\n    Integer.parseInt(lockManagerProperties.get(\"acquire.timeout-ms\")) < 1000) {\n  throw new IllegalArgumentException(\"acquire.timeout-ms must be configured with a sane value\");\n}","typeGuard":null,"tryCatchPattern":"try { lock.acquire(entityId, ownerId); } catch (IllegalStateException e) { /* check lock holder, backoff and retry */ }","preventionTips":["Configure lock.acquire.timeout-ms and heartbeat intervals explicitly","Monitor for stale locks in the metastore","Ensure unique ownerId per client instance"],"tags":["lock","concurrency","commit"],"backgroundTag":"invalid-state-transition","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}