apache/druid · warning

Skipping leadership for [%s] because session is null

Error message

Skipping leadership for [%s] because session is null

What it means

Warning logged when the loop acquired the Consul KV lock but the local session id has become null (e.g. cleared after an exception or invalidation), so the selector cannot safely promote itself to leader and skips leadership for this iteration. It guards against promoting with a stale/unknown session identity.

Source

Thrown at extensions-contrib/consul-extensions/src/main/java/org/apache/druid/consul/discovery/ConsulLeaderSelector.java:264

          if (!isSessionValid(sessionId)) {
            LOGGER.info("Follower session [%s] expired or invalid, recreating", shortSessionId(sessionId));
            sessionId = null;
            continue;
          }
        }

        boolean acquired = tryAcquireLock(sessionId);

        if (acquired && !leader.get()) {
          boolean interrupted = Thread.currentThread().isInterrupted();
          if (stopping || interrupted) {
            LOGGER.info(
                "Skipping leadership for [%s] because selector is stopping (interrupted=%s)",
                lockKey,
                interrupted
            );
          } else if (sessionId == null) {
            LOGGER.warn("Skipping leadership for [%s] because session is null", lockKey);
          } else if (validateLockOwnership(sessionId)) {
            long electionStart = System.nanoTime();
            becomeLeader();
            long electionLatency = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - electionStart);
            ConsulMetrics.emitTimer(emitter, "consul/leader/election_latency", electionLatency,
                "lock", lockKey);
          } else {
            LOGGER.warn("Lock ownership validation failed for [%s]; will retry", lockKey);
            emitOwnershipMismatchMetric();
          }
        } else if (!acquired && leader.get()) {
          loseLeadership();
        }

        if (leader.get()) {
          // Session renewal handled by sessionKeeperLoop; here we just verify lock ownership
          Thread.sleep(config.getService().getHealthCheckInterval().getMillis());
          if (sessionId != null && !validateLockOwnership(sessionId)) {

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. No direct action usually needed — the loop recreates a session on the next iteration and retries lock acquisition.
  2. If it recurs, investigate why sessions are being invalidated (renewal failures, TTL too short, agent restarts).
  3. Shorten healthCheckInterval so renewals (healthCheckInterval/3) comfortably outpace the TTL.
  4. Check for repeated 'Session Keeper: Failed to renew' warnings that indicate the root cause.
Defensive patterns

Strategy: retry

Type guard

if (sessionId == null) {
  sessionId = createSession(); // recreate before attempting promotion
}

Prevention

When it happens

Trigger: tryAcquireLock succeeded but sessionId was nulled concurrently — e.g. the catch block in leaderElectionLoop set sessionId=null after an error, or an isSessionValid check cleared it, between lock acquisition and the promotion branch.

Common situations: Race during Consul session expiry or error recovery: the session expired and was reset just as lock acquisition returned true from a prior session, or an error path (network failure) cleared sessionId mid-cycle.

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/e3cb0fc96f1fbc5d. Report an issue: GitHub.