apache/druid · error · IllegalStateException
Result partition information is not ready yet
Error message
Result partition information is not ready yet
What it means
ControllerStageTracker.getResultPartitions returns the ReadablePartitions for a stage's results, but until the stage finishes (or its partition count is known) the internal resultPartitions field is null. Callers that read partitions before the stage has reached a phase where partitions are known trigger this ISE — a guard against reading controller state too early.
Source
Thrown at multi-stage-query/src/main/java/org/apache/druid/msq/kernel/controller/ControllerStageTracker.java:241
{
return phase;
}
/**
* Whether partitions for the results of this stage have been set.
*/
boolean hasResultPartitions()
{
return resultPartitions != null;
}
/**
* Partitions for the results of the stage associated with this tracker.
*/
ReadablePartitions getResultPartitions()
{
if (resultPartitions == null) {
throw new ISE("Result partition information is not ready yet");
} else {
return resultPartitions;
}
}
/**
* @return Partition boundaries for the results of this stage
*/
ClusterByPartitions getResultPartitionBoundaries()
{
if (!getStageDefinition().doesShuffle()) {
throw new ISE("Result partition information is not relevant to this stage because it does not shuffle");
} else if (resultPartitionBoundaries == null) {
throw new ISE("Result partition information is not ready yet");
} else {
return resultPartitionBoundaries;
}
}View on GitHub (pinned to 9b90983fd2)
Solutions
- Check the stage phase before calling: only read partitions once the tracker reports the stage finished (or use a method that returns Optional/null for unknown partitions).
- Use ControllerQueryKernel's phase-based APIs (e.g. checking resultPrefix/readyForReading) instead of direct partition access during execution.
- If hit intermittently in logs, add a guard: if (tracker.getResultPartitionsIfKnown() == null) skip and re-check on next controller tick.
Example fix
// before
ReadablePartitions p = tracker.getResultPartitions();
// after
if (kernel.getStagePhase(stageId) == StagePhase.FINISHED) {
ReadablePartitions p = tracker.getResultPartitions();
} Defensive patterns
Strategy: retry
Validate before calling
if (kernel.getStagePhase(stageId) != StagePhase.FINISHED) {
// partitions not knowable yet — defer the read
return;
} Try / catch
try {
ReadablePartitions p = tracker.getResultPartitions();
} catch (IllegalStateException e) {
if (e.getMessage().contains("not ready yet")) {
// re-check on next controller tick
} else {
throw e;
}
} Prevention
- Only read result partitions after the stage reaches its finished phase.
- Prefer phase-gated kernel APIs over direct tracker field access in extensions.
- In polling loops, treat 'not ready' as expected and back off.
When it happens
Trigger: Calling getResultPartitions() while the tracked stage is still running (e.g. during READING_INPUT/POST_COMPUTATION phase) before resultPartitions is set by finish()/state advancement; also after controller restart if partition info was not persisted.
Common situations: Controller-side code that checks downstream readiness and assumes partitions are known as soon as a stage starts; custom controller extensions or debugging code polling result partitions mid-stage; race between stage completion callback and partition query.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Work order for worker[%d] not found for stage[%d]
- Number of partitions not known for [%s] with maxPartitions[%
- Cannot accept duplicate stage numbers
- Work order not present for stage[%s]
- Cannot start the stage: [%s]
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/eba7a036b7d2ae00.
Report an issue: GitHub.