apache/druid · warning · QueryTimeoutException

Query timeout, cancelling pending results for query

Error message

Query timeout, cancelling pending results for query [%s]. Per-segment timeout exceeded.

What it means

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.

Solutions

  1. Increase the per-segment timeout context value on the query
  2. Investigate the specific slow segment: check historical logs, segment size, whether it required a deep-store fetch, and warm it up (segment warming/cache)
  3. Reduce per-segment work via query filters or repartitioning overly large segments
  4. Check historical load (concurrency, GC, disk I/O) — per-segment timeouts usually indicate resource contention

Example fix

// before
query.getContext().put("timeout", "10000"); // per-segment budget too tight
// after
query.getContext().put("timeout", "60000"); // allow cold segments to load
Defensive patterns

Strategy: try-catch

Validate before calling

// check segment sizes/row counts to spot oversized segments
// SELECT segment_id, num_rows FROM sys.segments WHERE datasource='myDs'

Try / catch

try {
  results = client.query(queryJson);
} catch (QueryTimeoutException e) {
  if (e.getMessage().contains("Per-segment timeout exceeded")) {
    // raise per-segment timeout or investigate the slow segment
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/f2236523f6e25d28. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/query/ChainedExecutionQueryRunner.java:183

              ).iterator();
            }
            catch (CancellationException | InterruptedException e) {
              log.noStackTrace().warn(e, "Query interrupted, cancelling pending results for query [%s]", query.getId());
              GuavaUtils.cancelAll(true, future, futures);
              throw new QueryInterruptedException(e);
            }
            catch (TimeoutException | QueryTimeoutException e) {
              log.noStackTrace().warn(e, "Query timeout, cancelling pending results for query [%s]", query.getId());
              GuavaUtils.cancelAll(true, future, futures);
              throw new QueryTimeoutException(StringUtils.nonStrictFormat("Query [%s] timed out", query.getId()));
            }
            catch (ExecutionException e) {
              log.noStackTrace().warn(e, "Query error, cancelling pending results for query [%s]", query.getId());
              GuavaUtils.cancelAll(true, future, futures);
              Throwable cause = e.getCause();
              // Nested per-segment future timeout
              if (cause instanceof TimeoutException) {
                throw new QueryTimeoutException(StringUtils.nonStrictFormat("Query timeout, cancelling pending results for query [%s]. Per-segment timeout exceeded.", query.getId()));
              }
              Throwables.throwIfUnchecked(cause);
              throw new RuntimeException(cause);
            }
          }

          @Override
          public void cleanup(Iterator<T> tIterator)
          {

          }
        }
    );
  }
}

View on GitHub (pinned to 9b90983fd2)