{"record":{"id":"022454756cea9e33","repo":"apache/druid","slug":"failed-to-offer-result-to-output-queue","errorCode":null,"errorMessage":"Failed to offer result to output queue","messagePattern":"Failed to offer result to output queue","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/java/util/common/guava/ParallelMergeCombiningSequence.java","lineNumber":867,"sourceCode":"      }\n      return success;\n    }\n\n    @Override\n    public boolean isReleasable()\n    {\n      return item == null;\n    }\n\n    public void offer(ResultBatch<E> item)\n    {\n      try {\n        this.item = item;\n        ForkJoinPool.managedBlock(this);\n      }\n      catch (InterruptedException e) {\n        this.item = null;\n        throw new RuntimeException(\"Failed to offer result to output queue\", e);\n      }\n    }\n\n    public void tryOfferTerminal()\n    {\n      this.queue.offer(ResultBatch.terminal());\n    }\n  }\n\n  /**\n   * Holder object for an ordered batch of results from a sequence. Batching the results vastly reduces the amount of\n   * blocking that is needed to move results between stages of {@link MergeCombineAction} done in parallel, allowing\n   * the fork join tasks to focus on doing actual work instead of dealing with managed blocking.\n   */\n  static class ResultBatch<E>\n  {\n    static <T> ResultBatch<T> terminal()\n    {","sourceCodeStart":849,"sourceCodeEnd":885,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/java/util/common/guava/ParallelMergeCombiningSequence.java#L849-L885","documentation":"In ParallelMergeCombiningSequence, the ResultBatch consumer thread blocks offering results to the output queue via ForkJoinPool.managedBlock(). If the thread is interrupted while blocked, it wraps the InterruptedException in a RuntimeException with this message, abandoning the result batch.","triggerScenarios":"Query cancellation or shutdown interrupting the worker thread while it waits to offer a ResultBatch to a full output queue during parallel merge/combine of sequences.","commonSituations":"User cancels a long-running SQL/native query; server shutdown or timeout cancels in-flight parallel merges; downstream consumer stalls causing the output queue to fill.","solutions":["Inspect the cause chain for the original InterruptedException to confirm cancellation source","Treat this as expected during query cancellation; retry only if the interruption was spurious","Ensure downstream consumers drain the output queue promptly to avoid blocking offers"],"exampleFix":"// before\nSequence<ResultRow> seq = ParallelMergeCombiningSequence.create(...); // interrupted mid-merge\n// after\ntry (QueryLifecycle ql = ...) { ... } catch (RuntimeException e) {\n  if (e.getCause() instanceof InterruptedException) { /* cancellation path */ }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { /* consume merge sequence */ } catch (RuntimeException e) {\n  if (e.getCause() instanceof InterruptedException) { Thread.currentThread().interrupt(); /* treat as cancellation */ }\n  else throw e;\n}","preventionTips":["Avoid cancelling queries mid-merge unless intended","Keep output-queue consumers fast so offers rarely block","Shut down executors gracefully with cancellation-aware handling"],"tags":["parallelism","interruption","merge","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"}