apache/druid · error · QueryTimeoutException

Query [ ] timed out!

Error message

Query [%s] timed out!

What it means

JsonParserIterator.init() waits (with timeout) for the next batch from a remote queryable server. When the wait exceeds the timeout it throws QueryTimeoutException with "Query [%s] timed out!", tagged with the host, indicating the remote server failed to deliver results in time.

Solutions

  1. Increase the query/HTTP timeout configuration (e.g. druid processing timeout or http timeout for the client)
  2. Investigate the remote host named in the exception for load or GC issues
  3. Retry the query, ideally with query failover to another server
  4. Check network stability between client and server; look for dropped connections

Example fix

// before
// default timeout too small
// after
// druid.broker.http.readTimeout=PT10M (and matching query context timeout)
queryContext.setTimeout(600000L);
Defensive patterns

Strategy: retry

Validate before calling

// pre-check budget
long timeoutMs = queryContext.getTimeoutMs();
if (timeoutMs <= 0) throw new IllegalArgumentException("query timeout must be positive");

Try / catch

try { rows.hasNext(); } catch (QueryTimeoutException e) { log.warn("query {} timed out on host {}", queryId, e.getHost()); /* retry/failover */ }

Prevention

When it happens

Trigger: Remote broker/historical server slow or hung; large query exceeding configured HTTP/read timeout; network partition leaving the future incomplete until timeout; next()/hasNext() triggering lazy init on a stalled result stream.

Common situations: Distributed queries hitting an overloaded historical; config timeouts too low for heavy queries; dropped connections where the client never receives a response and waits until TimeoutException.

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/de0f89ceb55ad445. Report an issue: GitHub.

Appendix: source

Thrown at server/src/main/java/org/apache/druid/client/JsonParserIterator.java:219

          }
          throw convertException(
              new IAE(
                  "Next token wasn't a START_ARRAY, was[%s] from url[%s] with value[%s]",
                  jp.getCurrentToken(),
                  url,
                  errMsg
              )
          );
        }
      }
      catch (ExecutionException | CancellationException e) {
        throw convertException(e.getCause() == null ? e : e.getCause());
      }
      catch (IOException | InterruptedException e) {
        throw convertException(e);
      }
      catch (TimeoutException e) {
        throw new QueryTimeoutException(StringUtils.nonStrictFormat("Query [%s] timed out!", queryId), host);
      }
    }
  }

  private QueryTimeoutException timeoutQuery()
  {
    return new QueryTimeoutException(StringUtils.nonStrictFormat("url[%s] timed out", url), host);
  }

  /**
   * Converts the given exception to a proper type of {@link QueryException}.
   * The use cases of this method are:
   * <p>
   * - All non-QueryExceptions are wrapped with {@link QueryInterruptedException}.
   * - The QueryException from {@link DirectDruidClient} is converted to a more specific type of QueryException
   * based on {@link QueryException#getErrorCode()}. During conversion, {@link QueryException#host} is overridden
   * by {@link #host}.
   */

View on GitHub (pinned to 9b90983fd2)