apache/druid · warning
Worker: %s
Error message
Worker: %s
What it means
Same error path as the controller log: in ControllerImpl.runInternal, when a worker error report exists, it is logged as 'Worker: %s' after the controller error. This is the controller logging what a worker reported as the failure reason for the MSQ query.
Source
Thrown at multi-stage-query/src/main/java/org/apache/druid/msq/exec/ControllerImpl.java:520
// Cancellation triggered by an external error. Report the original error.
if (exceptionEncountered != null) {
cancelException.addSuppressed(exceptionEncountered);
}
errorForReport =
MSQErrorReport.fromException(queryId(), selfHost, null, cancelException, querySpec.getColumnMappings());
} else if (cancelReason != null) {
errorForReport = MSQErrorReport.fromFault(queryId(), selfHost, null, new CanceledFault(cancelReason));
} else {
errorForReport = MSQTasks.makeErrorReport(queryId(), selfHost, controllerError, workerError);
}
// Log the errors we encountered.
if (controllerError != null) {
log.warn("Controller: %s", MSQTasks.errorReportToLogMessage(controllerError, context.isDebug()));
}
if (workerError != null) {
log.warn("Worker: %s", MSQTasks.errorReportToLogMessage(workerError, context.isDebug()));
}
}
if (queryKernel != null && queryKernel.isSuccess()) {
// If successful, encourage workers to exit successfully.
// Only send this command to participating workers. For task-based queries, this is all tasks, since tasks
// are launched only when needed. For Dart, this is any servers that were actually assigned work items.
postFinishToWorkers(queryKernel.getAllParticipatingWorkers());
workerManager.stop(false);
} else {
// If not successful, cancel running tasks.
if (workerManager != null) {
workerManager.stop(true);
}
}
// Wait for worker tasks to exit. Ignore their return status. At this point, we've done everything we need to do,
// so we don't care about the task exit status.
if (workerTaskRunnerFuture != null) {View on GitHub (pinned to 9b90983fd2)
Solutions
- Read the rendered message after 'Worker:' — the fault class and message identify the worker-side root cause.
- Increase worker task memory (druid.indexer.runner javaOpts / MSQ task context maxWorkerMemory) if the cause is OOM or channel pressure.
- Check the specific task's logs on its host for the full stack trace of the reported worker fault.
Defensive patterns
Strategy: try-catch
Try / catch
try {
runMsqQuery(query);
} catch (MSQException e) {
// "Worker:" log names the worker fault; fetch that task's logs for the stack trace
fetchTaskLogsForFault(e);
} Prevention
- Give MSQ worker tasks adequate memory; OOM is a common worker-fault cause.
- Check the specific task logs on the worker host named in the report.
- Monitor shuffle/storage-connector health between controller and workers.
When it happens
Trigger: A MSQ query fails because one of its workers errored: channel/communication failures, OOM on a worker, stage execution exceptions, or data-source/segment read failures reported back to the controller.
Common situations: Workers die from insufficient memory (tune peon memory), storage connector issues during shuffle, or exceptions reading input segments; the controller then logs the worker report and the query fails with a Worker fault.
Related errors
- Controller: %s
- MSQFault from worker error report
- Worker[%d] not found for stage[%s]
- Worker on host %s does not exists
- Action [%s] failed for worker [%s] with status %s(%s)
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/2306faadc27468af.
Report an issue: GitHub.