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 somethingView on GitHub (pinned to 5720a38cfe)
Solutions
- 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.
- 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.
- 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.
- 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
- Prefer cursor-based (after/sort-boundary) pagination over offset paging in scripts
- Cap saved-query offsets in UI glue code before executing
- Alert when result counts approach 10000 - it usually means filters are too broad
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
- Maximum page size for Conduit API method calls is 100, but t
- All Fulltext Search hosts failed:
- Parameter "fullText" is no longer supported. Use method "man
- Too many relationships (%s, of type "%s").
- Minimum page size for API searches is 1, but this call speci
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/bfc73a5c90f8df24.
Report an issue: GitHub.