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
- Verify the StageId belongs to the same query and its stage number is within the created range (getStageCount/getStage)
- Check the query/controller lifecycle — the stage may have been cleaned up after completion or failure
- 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
- Only query stages created in the same kernel/query lifetime
- Check query state (RUNNING vs finished/canceled) before touching stage metadata
- Log and compare StageId queryIds on mismatch
- Avoid caching StageIds across controller restarts
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
- Invalid stageNumber [%s]
- Not a valid stage id: [%s]
- Writable channel is not available. The output channel might
- Frame allocator is not available. The output channel might b
- Cannot have both awaitChannels and awaitFutures
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/54f91cc83284f40e.
Report an issue: GitHub.