{"record":{"id":"e3cb0fc96f1fbc5d","repo":"apache/druid","slug":"skipping-leadership-for-s-because-session-is-nu","errorCode":null,"errorMessage":"Skipping leadership for [%s] because session is null","messagePattern":"Skipping leadership for \\[(.+?)\\] because session is null","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"extensions-contrib/consul-extensions/src/main/java/org/apache/druid/consul/discovery/ConsulLeaderSelector.java","lineNumber":264,"sourceCode":"          if (!isSessionValid(sessionId)) {\n            LOGGER.info(\"Follower session [%s] expired or invalid, recreating\", shortSessionId(sessionId));\n            sessionId = null;\n            continue;\n          }\n        }\n\n        boolean acquired = tryAcquireLock(sessionId);\n\n        if (acquired && !leader.get()) {\n          boolean interrupted = Thread.currentThread().isInterrupted();\n          if (stopping || interrupted) {\n            LOGGER.info(\n                \"Skipping leadership for [%s] because selector is stopping (interrupted=%s)\",\n                lockKey,\n                interrupted\n            );\n          } else if (sessionId == null) {\n            LOGGER.warn(\"Skipping leadership for [%s] because session is null\", lockKey);\n          } else if (validateLockOwnership(sessionId)) {\n            long electionStart = System.nanoTime();\n            becomeLeader();\n            long electionLatency = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - electionStart);\n            ConsulMetrics.emitTimer(emitter, \"consul/leader/election_latency\", electionLatency,\n                \"lock\", lockKey);\n          } else {\n            LOGGER.warn(\"Lock ownership validation failed for [%s]; will retry\", lockKey);\n            emitOwnershipMismatchMetric();\n          }\n        } else if (!acquired && leader.get()) {\n          loseLeadership();\n        }\n\n        if (leader.get()) {\n          // Session renewal handled by sessionKeeperLoop; here we just verify lock ownership\n          Thread.sleep(config.getService().getHealthCheckInterval().getMillis());\n          if (sessionId != null && !validateLockOwnership(sessionId)) {","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-contrib/consul-extensions/src/main/java/org/apache/druid/consul/discovery/ConsulLeaderSelector.java#L246-L282","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["No direct action usually needed — the loop recreates a session on the next iteration and retries lock acquisition.","If it recurs, investigate why sessions are being invalidated (renewal failures, TTL too short, agent restarts).","Shorten healthCheckInterval so renewals (healthCheckInterval/3) comfortably outpace the TTL.","Check for repeated 'Session Keeper: Failed to renew' warnings that indicate the root cause."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"if (sessionId == null) {\n  sessionId = createSession(); // recreate before attempting promotion\n}","tryCatchPattern":null,"preventionTips":["Ensure renewal cadence (healthCheckInterval/3) is well below the session TTL","Watch consul/leader/renew/fail metrics","Avoid too-short TTLs that expire during normal RPC latency"],"tags":["consul","race-condition","session","leader-election"],"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-14T11:17:12.474Z"}