{"record":{"id":"a04952a84db49d85","repo":"apache/iceberg","slug":"failed-to-acquire-zookeeper-lock-a04952","errorCode":null,"errorMessage":"Failed to acquire Zookeeper lock","messagePattern":"Failed to acquire Zookeeper lock","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/ZkLockFactory.java","lineNumber":218,"sourceCode":"    }\n\n    @Override\n    public boolean tryLock() {\n      VersionedValue<Integer> versionedValue = sharedCount.getVersionedValue();\n      if (isHeld(versionedValue)) {\n        LOG.debug(\"Lock is already held for path: {}\", lockPath);\n        return false;\n      }\n\n      try {\n        boolean acquired = sharedCount.trySetCount(versionedValue, LOCKED);\n        if (!acquired) {\n          LOG.debug(\"Failed to acquire lock for path: {}\", lockPath);\n        }\n\n        return acquired;\n      } catch (Exception e) {\n        LOG.warn(\"Failed to acquire Zookeeper lock\", e);\n        return false;\n      }\n    }\n\n    @Override\n    public boolean isHeld() {\n      return isHeld(sharedCount.getVersionedValue());\n    }\n\n    private static boolean isHeld(VersionedValue<Integer> versionedValue) {\n      try {\n        return versionedValue.getValue() == LOCKED;\n      } catch (Exception e) {\n        throw new RuntimeException(\"Failed to check Zookeeper lock status\", e);\n      }\n    }\n\n    @Override","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/ZkLockFactory.java#L200-L236","documentation":"ZkLockFactory.tryLock catches any Exception while attempting to acquire the ZooKeeper shared lock, logs this warning, and returns false instead of propagating. Callers see a failed lock acquisition (a retry is expected) rather than a thrown error.","triggerScenarios":"Exception thrown by the Curator SharedCount/InterProcessMutex operations inside tryLock — e.g. connection loss, session expiry, or KeeperException while setting the count on lockPath.","commonSituations":"ZooKeeper ensemble unreachable or flapping; session timeouts under load; wrong lock path or insufficient zNode permissions; maintenance coordinator triggering table maintenance while the ZK quorum is degraded.","solutions":["Inspect the logged stack trace for the underlying KeeperException (ConnectionLoss, SessionExpired, NoAuth)","Verify ZooKeeper connectivity, quorum health, and session timeouts","Check zNode ACLs/permissions for the configured lock path","Retry — tryLock returns false and the maintenance trigger will be attempted again"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// check ZK connectivity ahead of triggering maintenance\n curator.checkExists().forPath(lockPath);","typeGuard":null,"tryCatchPattern":"boolean acquired = lockFactory.tryLock();\nif (!acquired) { /* schedule retry on next trigger */ }","preventionTips":["Ensure the ZooKeeper ensemble is healthy and reachable from TaskManagers","Set correct ACLs on the lock path","Tune session/connection timeouts for expected maintenance durations"],"tags":["flink","zookeeper","lock","distributed-lock"],"backgroundTag":"lock-acquisition-failed","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"}