{"record":{"id":"f15224cada694dd0","repo":"apache/druid","slug":"query-interrupted-cancelling-pending-results-for","errorCode":null,"errorMessage":"Query interrupted, cancelling pending results for query [%s]","messagePattern":"Query interrupted, cancelling pending results for query \\[(.+?)\\]","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"processing/src/main/java/org/apache/druid/query/ChainedExecutionQueryRunner.java","lineNumber":168,"sourceCode":"                            return queryProcessingPool.submitRunnerTask(callable);\n                          }\n                        }\n                    )\n                );\n\n            ListenableFuture<List<Iterable<T>>> future = Futures.allAsList(futures);\n            queryWatcher.registerQueryFuture(query, future);\n\n            try {\n              return new MergeIterable<>(\n                  context.hasTimeout() ?\n                      future.get(context.getTimeout(), TimeUnit.MILLISECONDS) :\n                      future.get(),\n                  ordering.nullsFirst()\n              ).iterator();\n            }\n            catch (CancellationException | InterruptedException e) {\n              log.noStackTrace().warn(e, \"Query interrupted, cancelling pending results for query [%s]\", query.getId());\n              GuavaUtils.cancelAll(true, future, futures);\n              throw new QueryInterruptedException(e);\n            }\n            catch (TimeoutException | QueryTimeoutException e) {\n              log.noStackTrace().warn(e, \"Query timeout, cancelling pending results for query [%s]\", query.getId());\n              GuavaUtils.cancelAll(true, future, futures);\n              throw new QueryTimeoutException(StringUtils.nonStrictFormat(\"Query [%s] timed out\", query.getId()));\n            }\n            catch (ExecutionException e) {\n              log.noStackTrace().warn(e, \"Query error, cancelling pending results for query [%s]\", query.getId());\n              GuavaUtils.cancelAll(true, future, futures);\n              Throwable cause = e.getCause();\n              // Nested per-segment future timeout\n              if (cause instanceof TimeoutException) {\n                throw new QueryTimeoutException(StringUtils.nonStrictFormat(\"Query timeout, cancelling pending results for query [%s]. Per-segment timeout exceeded.\", query.getId()));\n              }\n              Throwables.throwIfUnchecked(cause);\n              throw new RuntimeException(cause);","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/ChainedExecutionQueryRunner.java#L150-L186","documentation":"ChainedExecutionQueryRunner.make() waits on per-segment futures and merges their results. On CancellationException or InterruptedException it cancels all remaining futures (GuavaUtils.cancelAll(true, ...)) and throws QueryInterruptedException, logging which query was interrupted. This is the fan-out runner's cleanup path for query cancellation or thread interruption.","triggerScenarios":"While future.get() is blocked waiting for a segment result: the query is cancelled via the cancellation endpoint, the client disconnects causing cancellation propagation, or the executing thread is interrupted (shutdown/timeout management).","commonSituations":"User cancels a long-running query from the Druid console/CLI; broker drops the HTTP connection to the client and cancels downstream work; server shutdown or interrupt-driven timeout on the query thread.","solutions":["Confirm the query was intentionally cancelled; this log is normal in that case","Check broker logs for the originating cancellation reason (client disconnect vs explicit cancel)","Reduce per-segment latency (increase numThreads, tune query timeouts) if cancellations come from client timeouts","Ensure clients close connections properly so cancellation propagates and resources are freed promptly"],"exampleFix":"// before: client aborts without cancelling server-side\ncurl ... > /dev/null &  # killed, server keeps running until disconnect detection\n// after: cancel explicitly\n// curl -X DELETE \"http://broker:8082/druid/v2/<queryId>\" or set client socket/read timeouts to match query.timeout","handlingStrategy":"try-catch","validationCode":"// Skip issuing a query you already know is cancelled\nif (cancelledQueryIds.contains(queryId)) {\n  throw new QueryInterruptedException(new CancellationException());\n}","typeGuard":null,"tryCatchPattern":"try {\n  result = queryRunner.run(queryPlus, responseContext).toList();\n} catch (QueryInterruptedException e) {\n  if (e.getCause() instanceof CancellationException || e.getCause() instanceof InterruptedException) {\n    log.info(\"Query %s was cancelled\", query.getId()); // expected path\n  } else {\n    throw e;\n  }\n}","preventionTips":["Align client-side timeouts with query context timeout so cancellation is deliberate","Always cancel explicitly (DELETE /druid/v2/<id>) when abandoning queries","Monitor cancellation rates — spikes indicate client timeouts or instability","Provide sufficient broker/historical threads to avoid long queue-induced timeouts"],"tags":["query-cancellation","interrupt","druid","distributed-query"],"backgroundTag":"request-timeout","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}