apache/druid · error · IllegalStateException

No such stage[%s]

Error message

No such stage[%s]

What it means

getStageOutputChannelMode looks up the stage's OutputChannelMode in the kernel's map and throws IllegalStateException 'No such stage[%s]' when the StageId is absent. The kernel only registers stages it has created, so querying a mode for an unknown or not-yet-created stage is an internal invariant violation.

Source

Thrown at multi-stage-query/src/main/java/org/apache/druid/msq/kernel/controller/ControllerQueryKernel.java:467

   * Returns the definition of a given stage.
   *
   * @throws NullPointerException if there is no stage with the given ID
   */
  public StageDefinition getStageDefinition(final StageId stageId)
  {
    return queryDef.getStageDefinition(stageId);
  }

  /**
   * Returns the {@link OutputChannelMode} for a given stage.
   *
   * @throws IllegalStateException if there is no stage with the given ID
   */
  public OutputChannelMode getStageOutputChannelMode(final StageId stageId)
  {
    final OutputChannelMode outputChannelMode = stageOutputChannelModes.get(stageId);
    if (outputChannelMode == null) {
      throw new ISE("No such stage[%s]", stageId);
    }

    return outputChannelMode;
  }

  /**
   * Whether query results are readable.
   */
  public boolean canReadQueryResults()
  {
    final StageId finalStageId = queryDef.getFinalStageDefinition().getId();
    final ControllerStageTracker stageTracker = stageTrackers.get(finalStageId);
    if (stageTracker == null) {
      return false;
    } else {
      final OutputChannelMode outputChannelMode = stageOutputChannelModes.get(finalStageId);
      if (outputChannelMode == OutputChannelMode.MEMORY) {
        return stageTracker.getPhase().isRunning();

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Verify the StageId belongs to the same query and its stage number is within the created range (getStageCount/getStage)
  2. Check the query/controller lifecycle — the stage may have been cleaned up after completion or failure
  3. Add the stage via createNewKernel before reading its channel mode, or guard the lookup with stageOutputChannelModes.containsKey

Example fix

// before
OutputChannelMode mode = kernel.getStageOutputChannelMode(stageId);
// after
if (!kernel.doesStageExist(stageId)) { throw new IllegalStateException("Stage not created: " + stageId); }
OutputChannelMode mode = kernel.getStageOutputChannelMode(stageId);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!kernel.doesStageExist(stageId) || !stageId.getQueryId().equals(queryDef.getQueryId())) { throw new IllegalStateException("Stage not available: " + stageId); }

Type guard

boolean stageExists(ControllerQueryKernel k, StageId id) { return k.getStages().stream().anyMatch(s -> s.getId().equals(id)); }

Try / catch

try { mode = kernel.getStageOutputChannelMode(stageId); } catch (IllegalStateException e) { log.warn("Stage {} not in kernel (query done or wrong id)", stageId); mode = OutputChannelMode.NONE; }

Prevention

When it happens

Trigger: Calling getStageOutputChannelMode with a StageId that was never added to the kernel, one already removed/cleaned up, or an id for a different query; ordering bugs where the method is called before the kernel stage is initialized.

Common situations: Custom controller code querying a stage after the query failed or was canceled and the kernel was torn down; mixing up StageIds across queries; race between stage creation and consumers requesting the channel mode.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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