apache/pulsar · error · SchedulerManager.UnknownWorkerException
Worker ${workerId} is not among the current workers in the s
Error message
Worker ${workerId} is not among the current workers in the system What it means
drainIfNotInProgress(workerId) checks the set of currently available workers; if the requested workerId is not among them it throws UnknownWorkerException ('Worker <id> is not among the current workers in the system'). You asked to drain a worker the cluster does not currently see as active.
Source
Thrown at pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/SchedulerManager.java:289
}
// A worker must be specified at this point. This would be set up by the caller.
Objects.requireNonNull(workerId);
// [We can get stricter, and require that every drain op be followed up with a cleanup of the
// corresponding worker before any other drain op, so that the drainOpStatusMap should be empty
// at the next drain operation.]
if (drainOpStatusMap.containsKey(workerId)) {
String warnString = "Worker " + workerId
+ " was not removed yet from SchedulerManager after previous drain op";
log.warn(warnString);
throw new WorkerNotRemovedAfterPriorDrainException();
}
if (!availableWorkers.contains(workerId)) {
log.info().attr("workerId", workerId)
.log("invokeDrain was called for a worker which is not currently active");
throw new UnknownWorkerException();
}
return drain(workerId);
} finally {
drainInProgressFlag.set(false);
}
} else {
throw new DrainInProgressException();
}
}
public LongRunningProcessStatus getDrainStatus(String workerId) {
long startTime = System.nanoTime();
LongRunningProcessStatus status = Optional.ofNullable(workerId).map(id ->
Optional.ofNullable(drainOpStatusMap.get(id)).map(opStatus ->
switch (opStatus) {
case DrainCompleted ->
LongRunningProcessStatus.forStatus(LongRunningProcessStatus.Status.SUCCESS);View on GitHub (pinned to 820761864e)
Solutions
- List current workers (worker stats / REST) and use an exact existing workerId.
- Verify the worker's configured workerId matches the value you pass.
- If the worker is gone, no drain is needed — just clean up its leftover assignment state if any.
Example fix
// before
worker.drainIfNotInProgress("worker-3"); // stale id
// after
if (!worker.getCurrentAvailableWorkers().contains("worker-3")) {
log.warn("worker-3 is not active; nothing to drain");
return;
}
worker.drainIfNotInProgress("worker-3"); Defensive patterns
Strategy: validation
Validate before calling
// confirm the worker is currently active
if (!worker.getCurrentAvailableWorkers().contains(workerId)) {
throw new IllegalArgumentException(workerId + " is not an active worker");
} Try / catch
try {
worker.drainIfNotInProgress(workerId);
} catch (UnknownWorkerException e) {
log.warn("Worker {} not active; refresh worker list", workerId);
} Prevention
- Fetch the live worker list and pick exact ids, not cached ones
- Keep scripts in sync with configured workerId values
- Skip drain if the worker already deregistered
When it happens
Trigger: Draining a workerId that was already removed/never existed; typo in workerId; the target worker crashed or lost metadata-store registration before the drain call; calling drain after the worker already deregistered.
Common situations: Stale configuration or scripts referencing a decommissioned worker; retrying a drain after the worker already went away; hostname/worker-id mismatch (using hostname vs configured worker id).
Related errors
- Worker ${workerId} was not yet removed after a prior drain o
- Another drain is in progress
- You must specify either a Fully Qualified Function Name (FQF
- You must specify a name for the function or a Fully Qualifie
- Cannot specify both jar and function-type
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/35caf95752e4a76b.
Report an issue: GitHub.