{"record":{"id":"f2236523f6e25d28","repo":"apache/druid","slug":"query-timeout-cancelling-pending-results-for-quer","errorCode":null,"errorMessage":"Query timeout, cancelling pending results for query [%s]. Per-segment timeout exceeded.","messagePattern":"Query timeout, cancelling pending results for query \\[(.+?)\\]\\. Per-segment timeout exceeded\\.","errorType":"exception","errorClass":"QueryTimeoutException","httpStatus":null,"severity":"warning","filePath":"processing/src/main/java/org/apache/druid/query/ChainedExecutionQueryRunner.java","lineNumber":183,"sourceCode":"              ).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);\n            }\n          }\n\n          @Override\n          public void cleanup(Iterator<T> tIterator)\n          {\n\n          }\n        }\n    );\n  }\n}\n","sourceCodeStart":165,"sourceCodeEnd":199,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/ChainedExecutionQueryRunner.java#L165-L199","documentation":"When an ExecutionException surfaces a TimeoutException as its cause while collecting segment futures, ChainedExecutionQueryRunner.make() reports specifically that a per-segment timeout was exceeded. The log message and thrown QueryTimeoutException tell the user the timeout originated at the individual segment execution level, not the overall query budget.","triggerScenarios":"A per-segment future (with its own timeout, e.g. via per-segment timeout context or segment-scoped executors) times out; the segment runner's future completes exceptionally with TimeoutException, wrapped by the outer future's ExecutionException.","commonSituations":"A single cold/slow segment (deep storage fetch, disk contention) blowing the per-segment deadline while other segments finish; per-segment timeout set too low for wide rows; historical under load so an individual segment scan exceeds its slice of the budget.","solutions":["Increase the per-segment timeout context value on the query","Investigate the specific slow segment: check historical logs, segment size, whether it required a deep-store fetch, and warm it up (segment warming/cache)","Reduce per-segment work via query filters or repartitioning overly large segments","Check historical load (concurrency, GC, disk I/O) — per-segment timeouts usually indicate resource contention"],"exampleFix":"// before\nquery.getContext().put(\"timeout\", \"10000\"); // per-segment budget too tight\n// after\nquery.getContext().put(\"timeout\", \"60000\"); // allow cold segments to load","handlingStrategy":"try-catch","validationCode":"// check segment sizes/row counts to spot oversized segments\n// SELECT segment_id, num_rows FROM sys.segments WHERE datasource='myDs'","typeGuard":null,"tryCatchPattern":"try {\n  results = client.query(queryJson);\n} catch (QueryTimeoutException e) {\n  if (e.getMessage().contains(\"Per-segment timeout exceeded\")) {\n    // raise per-segment timeout or investigate the slow segment\n  }\n}","preventionTips":["Raise the per-segment timeout context value for cold/large segments","Keep segment sizes in the recommended range to bound per-segment work","Warm caches for hot segments to avoid deep-store fetch delays","Watch historical GC/disk metrics; per-segment timeouts often flag contention"],"tags":["druid","per-segment-timeout","query-timeout","performance"],"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"}