{"record":{"id":"966a747e754740c3","repo":"apache/druid","slug":"failed-to-load-next-batch-of-results","errorCode":null,"errorMessage":"Failed to load next batch of results","messagePattern":"Failed to load next batch of results","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/java/util/common/guava/ParallelMergeCombiningSequence.java","lineNumber":1024,"sourceCode":"\n    BatchedResultsCursor(Ordering<E> ordering)\n    {\n      this.ordering = ordering;\n    }\n\n    public abstract void initialize();\n\n    public abstract void advance();\n\n    public abstract boolean isDone();\n\n    void nextBatch()\n    {\n      try {\n        ForkJoinPool.managedBlock(this);\n      }\n      catch (InterruptedException e) {\n        throw new RuntimeException(\"Failed to load next batch of results\", e);\n      }\n    }\n\n    @Override\n    public void close() throws IOException\n    {\n      // nothing to close for blocking queue, but yielders will need to clean up or they will leak resources\n    }\n\n    public E get()\n    {\n      return resultBatch.get();\n    }\n\n    @Override\n    public int compareTo(BatchedResultsCursor<E> o)\n    {\n      return ordering.compare(get(), o.get());","sourceCodeStart":1006,"sourceCodeEnd":1042,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/java/util/common/guava/ParallelMergeCombiningSequence.java#L1006-L1042","documentation":"The CombiningYielderAdapter-style nextBatch() in ParallelMergeCombiningSequence blocks via ForkJoinPool.managedBlock() waiting for the next ResultBatch from workers. An InterruptedException is wrapped in RuntimeException('Failed to load next batch of results').","triggerScenarios":"Thread interruption while advancing to the next result batch during iteration of a parallel merge combining sequence (after the first batch loaded successfully).","commonSituations":"Mid-stream query cancellation or timeout; broker or task shutdown while results are still streaming from parallel merge workers.","solutions":["Confirm whether the interruption was a deliberate cancel (check query cancellation logs/scheduler)","Retry the query if cancellation was unintended; adjust timeouts otherwise","Close the Yielder promptly on failure to release underlying batch yielders"],"exampleFix":"// before\nwhile (!yielder.isDone()) { yielder = yielder.next(init); } // interrupted mid-stream\n// after\ntry {\n  while (!yielder.isDone()) { yielder = yielder.next(init); }\n} catch (RuntimeException e) {\n  if (e.getCause() instanceof InterruptedException) { /* cancelled */ }\n  yielder.close();\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { yielder = yielder.next(init); } catch (RuntimeException e) {\n  if (e.getCause() instanceof InterruptedException) { Thread.currentThread().interrupt(); yielder.close(); return; }\n  throw e;\n}","preventionTips":["Always close yielders in finally/try-with-resources after interruptions","Avoid long consumer stalls that widen the interruption window","Monitor cancellation rates to distinguish ops issues from expected cancels"],"tags":["parallelism","interruption","streaming","druid"],"backgroundTag":"request-timeout","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"}