phacility/phabricator · error · Exception

Query offset is too large. offset+limit=%s (max=%s)

Error message

Query offset is too large. offset+limit=%s (max=%s)

What it means

PhabricatorElasticFulltextStorageEngine::buildSpec() enforces Elasticsearch's max_result_window (default 10000) before issuing a search: offset + limit must not exceed 10000, because ES deep-paginated from/size queries get extremely slow and ES itself rejects them. Phabricator surfaces this proactively with its own Exception instead of letting ES fail later.

Source

Thrown at src/applications/search/fulltextstorage/PhabricatorElasticFulltextStorageEngine.php:227

    $spec = array(
      '_source' => false,
      'query' => array(
        'bool' => $q->toArray(),
      ),
    );


    if (!$query->getParameter('query')) {
      $spec['sort'] = array(
        array('dateCreated' => 'desc'),
      );
    }

    $offset = (int)$query->getParameter('offset', 0);
    $limit =  (int)$query->getParameter('limit', 101);
    if ($offset + $limit > 10000) {
      throw new Exception(pht(
        'Query offset is too large. offset+limit=%s (max=%s)',
        $offset + $limit,
        10000));
    }
    $spec['from'] = $offset;
    $spec['size'] = $limit;

    return $spec;
  }

  public function executeSearch(PhabricatorSavedQuery $query) {
    $types = $query->getParameter('types');
    if (!$types) {
      $types = array_keys(
        PhabricatorSearchApplicationSearchEngine::getIndexableDocumentTypes());
    }

    // Don't use '/_search' for the case that there is something

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Narrow the query (projects, statuses, date ranges) so the result set fits within the first 10000 - deep paging is an anti-pattern for search UIs.
  2. Paginate with after_key/cursor-style ordering (sort by dateCreated/id and use the last hit as a boundary) instead of large offsets; the Conduit search 'after' cursor does exactly this.
  3. If you truly must deep-page and control the ES cluster, raise index.max_result_window in ES settings - accept the performance cost; do not change Phabricator's cap.
  4. Audit scripts that loop with offset += 100 and cap total processed documents at 10000 per query window.

Example fix

// before: deep offset pagination against ES
for ($off = 0; $off < 100000; $off += 100) {
  $saved->setParameter('offset', $off);
  $hits = $engine->executeSearch($saved);
}

// after: cursor by creation date, no offset
$last = 0;
do {
  $saved->setParameter('offset', 0);
  $saved->setParameter('createdStart', $last);
  $hits = $engine->executeSearch($saved);
  $last = end($hits)['dateCreated'];
} while (count($hits) == 100);
Defensive patterns

Strategy: validation

Validate before calling

$offset = (int)$saved->getParameter('offset', 0);
$limit  = (int)$saved->getParameter('limit', 100);
if ($offset + $limit > 10000) {
  // narrow the query window instead of deep paging
  $saved->setParameter('offset', 0);
  $saved->setParameter('createdStart', $checkpoint_date);
}

Type guard

function fitsResultWindow($offset, $limit, $max = 10000) { return ($offset + $limit) <= $max; }

Try / catch

try {
  $phids = $engine->executeSearch($saved);
} catch (Exception $ex) {
  if (strpos($ex->getMessage(), 'offset is too large') !== false) {
    $saved->setParameter('offset', 0);
    $phids = $engine->executeSearch($saved); // restart page with cursor instead
  }
}

Prevention

When it happens

Trigger: Executing a saved search with a large offset (e.g. offset 9900, limit 101 - the default limit is 101), or building a custom PhabricatorSavedQuery with limit/offset parameters summing over 10000; also user-driven paging deep into result sets when Elasticsearch is the configured fulltext engine (cluster.search-service-config).

Common situations: Users jumping to a very deep page of search results in the UI; scripts enumerating all matches with offset += limit loops; over-broad queries (missing filters) returning huge result counts that invite deep paging; ES clusters where admins lowered max_result_window below 10000 while Phabricator still assumes 10000.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/bfc73a5c90f8df24. Report an issue: GitHub.