{"record":{"id":"ba185fb434799357","repo":"apache/iceberg","slug":"failed-to-close-zklockfactory-for-lockid-ba185f","errorCode":null,"errorMessage":"Failed to close ZkLockFactory for lockId: {}","messagePattern":"Failed to close ZkLockFactory for lockId: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/ZkLockFactory.java","lineNumber":156,"sourceCode":"    } catch (Exception e) {\n      closeQuietly();\n      throw new RuntimeException(\"Failed to initialize SharedCount\", e);\n    }\n  }\n\n  private String getTaskSharePath() {\n    return LOCK_BASE_PATH + lockId + \"/task\";\n  }\n\n  private String getRecoverySharedPath() {\n    return LOCK_BASE_PATH + lockId + \"/recovery\";\n  }\n\n  private void closeQuietly() {\n    try {\n      close();\n    } catch (Exception e) {\n      LOG.warn(\"Failed to close ZkLockFactory for lockId: {}\", lockId, e);\n    }\n  }\n\n  @Override\n  public Lock createLock() {\n    return new ZkLock(getTaskSharePath(), taskSharedCount);\n  }\n\n  @Override\n  public Lock createRecoveryLock() {\n    return new ZkLock(getRecoverySharedPath(), recoverySharedCount);\n  }\n\n  @Override\n  public void close() throws IOException {\n    try {\n      if (taskSharedCount != null) {\n        taskSharedCount.close();","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/ZkLockFactory.java#L138-L174","documentation":"ZkLockFactory.closeQuietly is called from open() when initialization partially fails: it attempts close() and, if closing the ZooKeeper-based lock factory throws, logs this warning with the lockId instead of propagating. The original failure that triggered the cleanup remains the primary error; this warning only reports that resource cleanup also failed.","triggerScenarios":"ZkLockFactory.open() (or initialization) fails partway and calls closeQuietly(); close() throws (e.g. Curator/ZooKeeper client already closed or connection broken), producing this warning.","commonSituations":"ZooKeeper unreachable at startup so factory init fails and cleanup also throws; double-close of the Curator framework client; timeout during shutdown.","solutions":["Find and fix the original exception that caused open() to fail (usually a ZooKeeper connectivity or configuration problem).","Verify ZooKeeper connect string, session timeout, and that the ZK ensemble is reachable from the Flink cluster.","Ensure the Curator client is not closed twice (check lifecycle management of ZkLockFactory in the maintenance job)."],"exampleFix":"// before\nlockFactoryBuilder = ZkLockFactory.builder()\n    .setZkServers(\"wrong-host:2181\")\n    .setLockId(\"maintenance\");\n\n// after\nlockFactoryBuilder = ZkLockFactory.builder()\n    .setZkServers(\"zk1:2181,zk2:2181,zk3:2181\")\n    .setLockId(\"maintenance\");","handlingStrategy":"try-catch","validationCode":"// Pre-flight: confirm ZK reachable before opening the factory\ntry (Socket s = new Socket()) {\n  s.connect(new InetSocketAddress(zkHost, zkPort), 5000);\n}","typeGuard":null,"tryCatchPattern":"try {\n  lockFactory.open();\n} catch (Exception e) {\n  LOG.error(\"ZkLockFactory init failed (see also 'Failed to close ZkLockFactory' if cleanup also failed)\", e);\n  throw e;\n}","preventionTips":["Validate the ZooKeeper connect string and reachability before starting the maintenance job.","Avoid double-closing the Curator client; manage lifecycle in one place.","Monitor the 'Failed to close ZkLockFactory' warning as a symptom of a deeper init failure."],"tags":["flink","zookeeper","lock","resource-cleanup"],"backgroundTag":"resource-close-failed","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"}