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

  1. Read the rendered message after 'Worker:' — the fault class and message identify the worker-side root cause.
  2. Increase worker task memory (druid.indexer.runner javaOpts / MSQ task context maxWorkerMemory) if the cause is OOM or channel pressure.
  3. 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

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


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