languagetool-org/languagetool · error · SearchTimeoutException

Search timeout of + maxSearchTimeMillis + ms reached for que

Error message

Search timeout of + maxSearchTimeMillis + ms reached for query + query

What it means

Searcher.findRuleMatchesOnIndex runs the Lucene search on a worker thread and joins it with a timeout. If the thread is still alive after maxSearchTimeMillis, the thread is interrupted and this SearchTimeoutException is thrown. It means the index query could not finish within the configured time budget.

Source

Thrown at languagetool-wikipedia/src/main/java/org/languagetool/dev/index/Searcher.java:183

      SearchRunnable runnable = new SearchRunnable(indexSearcher, query, languageTool);
      Thread searchThread = new Thread(runnable);
      searchThread.start();
      try {
        // using a TimeLimitingCollector is not enough, as it doesn't cover all time required to
        // search for a complicated regex, so interrupt the whole thread instead:
        if (limitSearch) { // I don't know a simpler way to achieve this...
          searchThread.join(maxSearchTimeMillis);
        } else {
          searchThread.join(Integer.MAX_VALUE);
        }
      } catch (InterruptedException e) {
        throw new RuntimeException("Search thread got interrupted for query " + query, e);
      }
      if (searchThread.isAlive()) {
        // join() timed out and the thread is still running, so its result isn't ready yet -
        // interrupt it and bail out instead of falling through with a null result
        searchThread.interrupt();
        throw new SearchTimeoutException("Search timeout of " + maxSearchTimeMillis + "ms reached for query " + query);
      }
      Exception exception = runnable.getException();
      if (exception != null) {
        if (exception instanceof SearchTimeoutException) {
          throw (SearchTimeoutException)exception;
        }
        throw new RuntimeException("Exception during search for query " + query + " on rule " + rule.getId(), exception);
      }

      List<MatchingSentence> matchingSentences = runnable.getMatchingSentences();
      SearcherResult searcherResult = new SearcherResult(matchingSentences, runnable.docsChecked, query);
      searcherResult.setMaxDocChecked(runnable.getMaxDocChecked());
      searcherResult.setHasTooManyLuceneMatches(runnable.hasTooManyLuceneMatches());
      searcherResult.setLuceneMatchCount(runnable.getLuceneMatchCount());
      searcherResult.setSkipHits(skipHits);
      searcherResult.setNumDocs(runnable.numDocs);
      if (runnable.hasTooManyLuceneMatches()) {
        // more potential matches than we can check in an acceptable time :-(

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Increase the maxSearchTimeMillis timeout value passed to the search
  2. Narrow the query or the pattern rule so fewer documents are scanned
  3. Optimize/compact the Lucene index and ensure it is on fast local storage
  4. Run the search on a smaller corpus subset first to validate the rule

Example fix

// before
SearcherResult result = searcher.findRuleMatchesOnIndex(query, rule, maxSearchTimeMillis = 5000);
// after
SearcherResult result = searcher.findRuleMatchesOnIndex(query, rule, 60000); // raise timeout
Defensive patterns

Strategy: try-catch

Validate before calling

if (maxSearchTimeMillis <= 0 || query == null) throw new IllegalArgumentException("query required, positive timeout");

Try / catch

try {
  result = searcher.findRuleMatchesOnIndex(query, rule, timeout);
} catch (SearchTimeoutException e) {
  LOG.warn("timeout for " + query + "; retrying with " + timeout*4);
  result = searcher.findRuleMatchesOnIndex(query, rule, timeout * 4);
}

Prevention

When it happens

Trigger: Calling findRuleMatchesOnIndex with a query whose Lucene search takes longer than maxSearchTimeMillis (large index, overly broad query, slow disk, missing index optimization).

Common situations: Running the Wikipedia corpus tooling against a large or poorly optimized Lucene index; queries with too-broad regex/pattern rules scanning huge numbers of docs; slow I/O on shared hardware.

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 languagetool-org/languagetool@2e990059ce (2026-09-06). Data as JSON: /api/errors/9b8a31810f1e3755. Report an issue: GitHub.