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
- Inspect the RuntimeException's cause (getCause()) for the real ApiException.
- Ensure registerListener() was called and the leader elector started before querying the leader.
- Fix the underlying K8s access issue (RBAC, token, namespace) per the cause.
- 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
- Call registerListener and wait for the elector to start before querying the leader.
- Always inspect getCause() — the bare RuntimeException hides the real ApiException.
- Handle 'no leader yet' as a normal state during startup.
- Fix RBAC/namespace issues surfaced by the cause.
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.