apache/druid · warning · ServiceUnavailableException

Can't find chatHandler for handler

Error message

Can't find chatHandler for handler[%s]

What it means

doTaskChat looks up the requested ChatHandler among handlers registered on this peon. When no handler is registered for handlerId, the resource throws ServiceUnavailableException (HTTP 503) so that SpecificTaskRetryPolicy on the client side retries — the handler may not be registered yet (task still starting) or was already unregistered during shutdown.

Solutions

  1. Simply retry — 503 is intentional and SpecificTaskRetryPolicy will back off and retry automatically
  2. Verify the task is still running via the overlord task status API before calling its chat endpoints
  3. Check task location data is current; stale routing sends requests to the wrong peon
  4. If it persists, check task logs for early startup failure that prevented ChatHandler registration
Defensive patterns

Strategy: retry

Validate before calling

// Check task is running before calling its chat endpoint
TaskStatus status = overlordClient.status(taskId).get();
if (status.getState() != TaskState.RUNNING) throw new IllegalStateException("Task not running");

Try / catch

try {
  return chatClient.call(handlerId);
} catch (ServiceUnavailableException e) {
  return RetryUtils.retry(() -> chatClient.call(handlerId), shouldRetry503, MAX_ATTEMPTS);
}

Prevention

When it happens

Trigger: Calling a task's chat endpoint (e.g. a Kafka ingestion task's /handoff or status endpoint) before the task registered its ChatHandler, after the task completed and unregistered it, or when the request was routed to a peon not actually hosting that task.

Common situations: Race right after task launch when clients query status too eagerly; querying a completed/killed task; stale task-location info in overlord causing requests to the wrong host/port.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at server/src/main/java/org/apache/druid/segment/realtime/ChatHandlerResource.java:80

      // Sanity check: Callers set TASK_ID_HEADER to our taskId (URL-encoded, if >= 0.14.0) if they want to be
      // assured of talking to the correct task, and not just some other task running on the same port.
      if (requestTaskId != null
          && !requestTaskId.equals(taskId)
          && !StringUtils.urlDecode(requestTaskId).equals(taskId)) {
        throw new BadRequestException(
            StringUtils.format("Requested taskId[%s] doesn't match with taskId[%s]", requestTaskId, taskId)
        );
      }
    }

    final Optional<ChatHandler> handler = handlers.get(handlerId);

    if (handler.isPresent()) {
      return handler.get();
    }

    // Return HTTP 503 so SpecificTaskRetryPolicy retries in case the handler is not registered yet or has been registered before shutdown.
    throw new ServiceUnavailableException(StringUtils.format("Can't find chatHandler for handler[%s]", handlerId));
  }
}

View on GitHub (pinned to 9b90983fd2)