apache/druid · warning

Failed to close LeaderLatch.

Error message

Failed to close LeaderLatch.

What it means

In unregisterListener(), CloseableUtils.closeAndSuppressExceptions failed to close the current LeaderLatch (e.g. it was already closed or the Curator client's connection was broken) and the exception is logged as a warning rather than propagated. Listener registration is torn down regardless.

Solutions

  1. Verify lifecycle ordering: call unregisterListener() exactly once per CuratorDruidLeaderSelector, from the stop phase only.
  2. Check whether ZK connectivity was down at shutdown; if so the warning is expected and the ephemeral node will be cleaned by session expiry.
  3. Look for a preceding 'Could not close old leader latch' warning indicating the latch was swapped concurrently.
  4. If the latch instance is stale, restart the service to rebuild a fresh latch.
Defensive patterns

Strategy: try-catch

Try / catch

// tolerate latch cleanup failure during shutdown
try {
  leaderSelector.unregisterListener();
} catch (Exception e) {
  log.warn(e, "Leader latch cleanup failed during shutdown; ephemeral node expires with session");
}

Prevention

When it happens

Trigger: Calling unregisterListener() when the leader latch was already closed (stopAndCreateNewLeaderLatch or a previous unregister), or when the underlying CuratorFramework/ZooKeeper session is broken so the close RPC fails.

Common situations: Service shutdown during a ZK outage, double lifecycle stop, or unregister racing with an in-flight latch swap after leadership loss.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

      lifecycleLock.started();
    }
    catch (Exception ex) {
      throw new RuntimeException(ex);
    }
    finally {
      lifecycleLock.exitStart();
    }
  }

  @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();
    }

View on GitHub (pinned to 9b90983fd2)