{"record":{"id":"8116cd64694bec54","repo":"apache/druid","slug":"could-not-close-old-leader-latch-continuing-with","errorCode":null,"errorMessage":"Could not close old leader latch; continuing with new one anyway.","messagePattern":"Could not close old leader latch; continuing with new one anyway\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"server/src/main/java/org/apache/druid/curator/discovery/CuratorDruidLeaderSelector.java","lineNumber":216,"sourceCode":"    }\n  }\n\n  @Override\n  public void unregisterListener()\n  {\n    if (!lifecycleLock.canStop()) {\n      throw new ISE(\"can't stop.\");\n    }\n\n    CloseableUtils.closeAndSuppressExceptions(leaderLatch.get(), e -> log.warn(e, \"Failed to close LeaderLatch.\"));\n    listenerExecutor.shutdownNow();\n  }\n\n  private void stopAndCreateNewLeaderLatch()\n  {\n    CloseableUtils.closeAndSuppressExceptions(\n        createNewLeaderLatchWithListener(),\n        e -> log.warn(\"Could not close old leader latch; continuing with new one anyway.\")\n    );\n  }\n\n  private void startLeaderLatch()\n  {\n    try {\n      //Small delay before starting the latch so that others waiting are chosen to become leader.\n      Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000));\n      leaderLatch.get().start();\n    }\n    catch (Throwable e) {\n      // If an exception gets thrown out here, then the node will zombie out 'cause it won't be looking for\n      // the latch anymore.  I don't believe it's actually possible for an Exception to throw out here, but\n      // Curator likes to have \"throws Exception\" on methods so it might happen...\n      log.makeAlert(e, \"I am a zombie\").emit();\n    }\n  }\n}","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/curator/discovery/CuratorDruidLeaderSelector.java#L198-L234","documentation":"stopAndCreateNewLeaderLatch() closes the old LeaderLatch via CloseableUtils.closeAndSuppressExceptions and immediately creates a replacement. If closing the old latch throws (already closed, ZK session broken), the error is swallowed with this warning because proceeding with the new latch is safe — the old latch will be cleaned up by ZK session expiry if needed.","triggerScenarios":"notLeader() triggering a latch recreation while the old latch is already closed or the Curator session is disconnected, so the old latch's close() fails.","commonSituations":"ZK session loss/expiry, leadership lost during a network partition, or an old latch that was concurrently closed by unregisterListener().","solutions":["No action required — the code intentionally continues with the new latch; check that a subsequent 'Starting leader selection sequence' log confirms the new latch started.","If the new latch never becomes leader, investigate ZK connectivity and session timeouts.","Avoid concurrent lifecycle calls (unregisterListener during leadership churn) that close latches out of band.","Ensure ZK servers are healthy and session timeout is adequate for the environment."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Confirm the replacement latch actually starts (watch the subsequent leadership logs).","Maintain healthy ZK connectivity so latch closes/recreates succeed cleanly.","Avoid concurrent lifecycle operations on the leader selector during churn."],"tags":["zookeeper","curator","leader-election","failover"],"backgroundTag":"invalid-state-transition","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}