apache/druid · warning

Could not close old leader latch; continuing with new one…

Error message

Could not close old leader latch; continuing with new one anyway.

What it means

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.

Solutions

  1. 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.
  2. If the new latch never becomes leader, investigate ZK connectivity and session timeouts.
  3. Avoid concurrent lifecycle calls (unregisterListener during leadership churn) that close latches out of band.
  4. Ensure ZK servers are healthy and session timeout is adequate for the environment.
Defensive patterns

Strategy: retry

Prevention

When it happens

Trigger: 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.

Common situations: ZK session loss/expiry, leadership lost during a network partition, or an old latch that was concurrently closed by unregisterListener().

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/8116cd64694bec54. Report an issue: GitHub.

Appendix: source

Thrown at server/src/main/java/org/apache/druid/curator/discovery/CuratorDruidLeaderSelector.java:216

    }
  }

  @Override
  public void unregisterListener()
  {
    if (!lifecycleLock.canStop()) {
      throw new ISE("can't stop.");
    }

    CloseableUtils.closeAndSuppressExceptions(leaderLatch.get(), e -> log.warn(e, "Failed to close LeaderLatch."));
    listenerExecutor.shutdownNow();
  }

  private void stopAndCreateNewLeaderLatch()
  {
    CloseableUtils.closeAndSuppressExceptions(
        createNewLeaderLatchWithListener(),
        e -> log.warn("Could not close old leader latch; continuing with new one anyway.")
    );
  }

  private void startLeaderLatch()
  {
    try {
      //Small delay before starting the latch so that others waiting are chosen to become leader.
      Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000));
      leaderLatch.get().start();
    }
    catch (Throwable e) {
      // If an exception gets thrown out here, then the node will zombie out 'cause it won't be looking for
      // the latch anymore.  I don't believe it's actually possible for an Exception to throw out here, but
      // Curator likes to have "throws Exception" on methods so it might happen...
      log.makeAlert(e, "I am a zombie").emit();
    }
  }
}

View on GitHub (pinned to 9b90983fd2)