{"record":{"id":"13b755485caf6741","repo":"apache/druid","slug":"stage-d-output-partitions-not-available","errorCode":null,"errorMessage":"Stage[%d] output partitions not available","messagePattern":"Stage\\[(.+?)\\] output partitions not available","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"multi-stage-query/src/main/java/org/apache/druid/msq/input/stage/StageInputSpecSlicer.java","lineNumber":69,"sourceCode":"    this.stageOutputChannelModeMap = stageOutputChannelModeMap;\n  }\n\n  @Override\n  public boolean canSliceDynamic(InputSpec inputSpec)\n  {\n    return false;\n  }\n\n  @Override\n  public List<InputSlice> sliceStatic(InputSpec inputSpec, @Nullable SegmentPruner segmentPruner, int maxNumSlices)\n  {\n    final StageInputSpec stageInputSpec = (StageInputSpec) inputSpec;\n\n    final ReadablePartitions stagePartitions = stagePartitionsMap.get(stageInputSpec.getStageNumber());\n    final OutputChannelMode outputChannelMode = stageOutputChannelModeMap.get(stageInputSpec.getStageNumber());\n\n    if (stagePartitions == null) {\n      throw new ISE(\"Stage[%d] output partitions not available\", stageInputSpec.getStageNumber());\n    }\n\n    if (outputChannelMode == null) {\n      throw new ISE(\"Stage[%d] output mode not available\", stageInputSpec.getStageNumber());\n    }\n\n    // Decide how many workers to use, and assign inputs.\n    final List<ReadablePartitions> workerPartitions = stagePartitions.split(maxNumSlices);\n    final List<InputSlice> retVal = new ArrayList<>();\n\n    for (final ReadablePartitions partitions : workerPartitions) {\n      retVal.add(\n          new StageInputSlice(\n              stageInputSpec.getStageNumber(),\n              partitions,\n              outputChannelMode\n          )\n      );","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/multi-stage-query/src/main/java/org/apache/druid/msq/input/stage/StageInputSpecSlicer.java#L51-L87","documentation":"StageInputSpecSlicer.sliceStatic reads a map from stage number to that stage's ReadablePartitions. When the map has no entry for the requested stage, the stage's output partition info is not yet available (or never recorded), and this ISE is thrown.","triggerScenarios":"sliceStatic on a StageInputSpec referencing stageNumber N where stagePartitionsMap.get(N) returns null - the upstream stage hasn't finished/published output, or the slicer was built without info for that stage.","commonSituations":"Query kernel bugs where a stage's inputs are sliced before the producer stage completes; incorrect stage numbering after DAG construction changes; attempting to slice a stage that reads from itself or a not-yet-created stage.","solutions":["Confirm the referenced stage number exists in the query's stage DAG and that its output is generated before slicing.","Check the WorkerStagePhases/counter map construction to ensure every consuming stage has a producer entry.","If this appears intermittently during query execution, collect controller logs and file a Druid MSQ bug - it indicates a kernel sequencing bug."],"exampleFix":"// before: slicing inputs before producer stage counters are known\nslicer.sliceStatic(inputSpec, maxSlices); // map lacks stage 2\n// after: only slice stage inputs once producer stage output is published\nif (stagePartitionsMap.containsKey(stageNumber)) {\n  slicer.sliceStatic(inputSpec, maxSlices);\n}","handlingStrategy":"validation","validationCode":"if (!stagePartitionsMap.containsKey(stageNumber)) {\n  throw new IllegalStateException(\"Producer stage \" + stageNumber + \" output not available yet\");\n}\nslicer.sliceStatic(inputSpec, maxSlices);","typeGuard":null,"tryCatchPattern":"try {\n  slicer.sliceStatic(inputSpec, maxSlices);\n} catch (IllegalStateException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"output partitions not available\")) {\n    log.error(e, \"Stage output missing; check kernel stage ordering\");\n  } else {\n    throw e;\n  }\n}","preventionTips":["Slice stage inputs only after the producer stage has published output.","Keep stage numbering consistent between the DAG and the kernel maps.","Add assertions that both maps share the same key set."],"tags":["msq","stage-dependency","missing-state","internal-error"],"backgroundTag":"resource-not-found","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}