apache/druid · error · RuntimeException

RuntimeException

Error message

RuntimeException

What it means

K8sDruidLeaderSelector.getCurrentLeader() catches any Exception from the delegate leader latch's getCurrentLeader and rethrows it as a bare RuntimeException, losing the original type and message context. The underlying cause is a Kubernetes API failure or elector state error while resolving the current leader.

Source

Thrown at extensions-core/kubernetes-extensions/src/main/java/org/apache/druid/k8s/discovery/K8sDruidLeaderSelector.java:112

            leader = false;
            listener.stopBeingLeader();
          }
          catch (Throwable ex) {
            LOGGER.makeAlert(ex, "listener.stopBeingLeader() failed. Unable to stopBeingLeader").emit();
          }
        }
    );
  }

  @Nullable
  @Override
  public String getCurrentLeader()
  {
    try {
      return leaderLatch.getCurrentLeader();
    }
    catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  public boolean isLeader()
  {
    return leader;
  }

  @Override
  public int localTerm()
  {
    return term;
  }

  @Override
  public void registerListener(DruidLeaderSelector.Listener listener)
  {

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Inspect the RuntimeException's cause (getCause()) for the real ApiException.
  2. Ensure registerListener() was called and the leader elector started before querying the leader.
  3. Fix the underlying K8s access issue (RBAC, token, namespace) per the cause.
  4. Prefer logging-and-defaulting over rethrow if the caller only needs a best-effort leader hint.

Example fix

// before
catch (Exception e) { throw new RuntimeException(e); }
// after
catch (Exception e) { throw new RE(e, "Failed to get current leader for [%s]", latchName); }
Defensive patterns

Strategy: try-catch

Type guard

boolean leaderElectorStarted(K8sDruidLeaderSelector s) { try { s.getCurrentLeader(); return true; } catch (RuntimeException e) { return false; } }

Try / catch

try {
  String leader = leaderSelector.getCurrentLeader();
} catch (RuntimeException e) {
  Throwable cause = e.getCause();
  LOG.warn(cause, "Leader lookup failed; treating as unknown");
  leader = null;
}

Prevention

When it happens

Trigger: Calling getCurrentLeader on K8sDruidLeaderSelector when the underlying K8sLeaderElector/leaderLatch fails — e.g. ApiException from fetching the lock, or the latch isn't started yet.

Common situations: Querying the leader before registerListener/startLeaderElector; K8s API errors (RBAC/auth/network) when reading the Lease; concurrent lifecycle calls.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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