apache/druid · error · RuntimeException (Druid RE)
Failed to get current leader for [%s]
Error message
Failed to get current leader for [%s]
What it means
Wraps a Kubernetes ApiException thrown while reading the holder identity of the leader-election lock (a CoordinationV1Api Lease/ConfigMap lock). The elector could not fetch the current lock object, so the current leader is unknown.
Source
Thrown at extensions-core/kubernetes-extensions/src/main/java/org/apache/druid/k8s/discovery/DefaultK8sLeaderElectorFactory.java:70
LeaderElectionConfig leaderElectionConfig =
new LeaderElectionConfig(
lock,
Duration.ofMillis(discoveryConfig.getLeaseDuration().getMillis()),
Duration.ofMillis(discoveryConfig.getRenewDeadline().getMillis()),
Duration.ofMillis(discoveryConfig.getRetryPeriod().getMillis())
);
LeaderElector leaderElector = new LeaderElector(leaderElectionConfig);
return new K8sLeaderElector()
{
@Override
public String getCurrentLeader()
{
try {
return lock.get().getHolderIdentity();
}
catch (ApiException ex) {
throw new RE(ex, "Failed to get current leader for [%s]", lockResourceName);
}
}
@Override
public void run(Runnable startLeadingHook, Runnable stopLeadingHook)
{
leaderElector.run(startLeadingHook, stopLeadingHook);
}
};
}
private Lock createLock(String candidateId, String namespace, String lockResourceName, ApiClient k8sApiClient)
{
return new ConfigMapLock(
namespace,
lockResourceName,
candidateId,
k8sApiClientView on GitHub (pinned to 9b90983fd2)
Solutions
- Grant the service account get on the lock resource (leases in coordination.k8s.io for the namespace).
- Verify the lock resource name and namespace in druid.k8s leader-election config exist (kubectl get lease <name> -n <ns>).
- Fix auth (valid service-account token) if the code is 401.
- Retry on transient errors; the message identifies which lock failed via lockResourceName.
Example fix
// before: kubectl auth can-i get leases.coordination.k8s.io -n druid => no // after: grant RBAC kubectl create role druid-leader --verb=get,list,watch --resource=leases.coordination.k8s.io -n druid kubectl create rolebinding druid-leader --role=druid-leader --serviceaccount=druid:druid-sa -n druid
Defensive patterns
Strategy: retry
Validate before calling
// before electing: check lock access kubectl auth can-i get leases.coordination.k8s.io -n <namespace> # must be yes kubectl get lease <lockResourceName> -n <namespace> # must exist
Try / catch
try {
String leader = elector.getCurrentLeader();
} catch (RE e) {
if (e.getCause() instanceof ApiException && ((ApiException) e.getCause()).getCode() == 404) {
return null; // no leader yet
}
throw e;
} Prevention
- Grant get/list/watch on leases (or the lock configmap) to the Druid service account.
- Ensure lockResourceName and namespace in config match the created Lease object.
- Create the Lease up-front if you don't want 404s before first election.
- Retry transient API errors with backoff.
When it happens
Trigger: Calling getCurrentLeader on the leader elector created by DefaultK8sLeaderElectorFactory when the underlying lock.get() request to the K8s API fails (403 RBAC, 404 missing lock object, 401 auth, network error).
Common situations: Service account missing get permission on the Lease/configmap used as lock; lockResourceName/namespace misconfigured; lock object deleted; transient API server errors.
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
- Expection in watching pods, code[%d] and error[%s].
- Failed to announce DiscoveryDruidNode[%s]
- RuntimeException
- can't start.
- can't stop.
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/fd30b9568cd449f2.
Report an issue: GitHub.