{"record":{"id":"1c8f5614b5676217","repo":"apache/druid","slug":"cannot-apply-limit-d-with-offset-d-due-to-over-1c8f56","errorCode":null,"errorMessage":"Cannot apply limit[%d] with offset[%d] due to overflow","messagePattern":"Cannot apply limit\\[(.+?)\\] with offset\\[(.+?)\\] due to overflow","errorType":"exception","errorClass":"IllegalStateException (ISE)","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/scan/ScanQueryQueryToolChest.java","lineNumber":83,"sourceCode":"  {\n    this.queryMetricsFactory = queryMetricsFactory;\n  }\n\n  @Override\n  public QueryRunner<ScanResultValue> mergeResults(final QueryRunner<ScanResultValue> runner)\n  {\n    return (queryPlus, responseContext) -> {\n      final ScanQuery originalQuery = ((ScanQuery) (queryPlus.getQuery()));\n      ScanQuery.verifyOrderByForNativeExecution(originalQuery);\n\n      // Remove \"offset\" and add it to the \"limit\" (we won't push the offset down, just apply it here, at the\n      // merge at the top of the stack).\n      final long newLimit;\n      if (!originalQuery.isLimited()) {\n        // Unlimited stays unlimited.\n        newLimit = Long.MAX_VALUE;\n      } else if (originalQuery.getScanRowsLimit() > Long.MAX_VALUE - originalQuery.getScanRowsOffset()) {\n        throw new ISE(\n            \"Cannot apply limit[%d] with offset[%d] due to overflow\",\n            originalQuery.getScanRowsLimit(),\n            originalQuery.getScanRowsOffset()\n        );\n      } else {\n        newLimit = originalQuery.getScanRowsLimit() + originalQuery.getScanRowsOffset();\n      }\n\n      final ScanQuery queryToRun = originalQuery.withOffset(0)\n                                                .withLimit(newLimit);\n\n      final Sequence<ScanResultValue> results;\n\n      if (!queryToRun.isLimited()) {\n        results = runner.run(queryPlus.withQuery(queryToRun), responseContext);\n      } else {\n        results = new BaseSequence<>(\n            new BaseSequence.IteratorMaker<ScanResultValue, ScanQueryLimitRowIterator>()","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/scan/ScanQueryQueryToolChest.java#L65-L101","documentation":"When merging scan results across segments/distributed sub-queries, the tool chest folds the query's offset into the effective limit (newLimit = limit + offset). If that addition overflows Long (limit > Long.MAX_VALUE - offset), it throws ISE because the merged limit cannot be represented.","triggerScenarios":"Calling ScanQueryQueryToolChest.mergeResults on a query with isLimited() true and getScanRowsLimit() so large that limit + getScanRowsOffset() exceeds Long.MAX_VALUE.","commonSituations":"Clients sending an astronomically large scanRowsLimit (e.g. Long.MAX_VALUE) together with a nonzero offset; programmatic query builders copying sentinel max-limit values and then adding pagination offsets.","solutions":["Reduce the scanRows limit to a sane value so limit+offset fits in a long","Remove the offset, or drop the limit so the query is unlimited","Clamp limit client-side, e.g. Math.min(limit, Long.MAX_VALUE - offset)"],"exampleFix":"// before\n{\"queryType\":\"scan\",\"limit\":9223372036854775807,\"offset\":100,...}\n// after\n{\"queryType\":\"scan\",\"limit\":1000000,\"offset\":100,...}","handlingStrategy":"validation","validationCode":"if (query.isLimited() && query.getScanRowsLimit() > Long.MAX_VALUE - query.getScanRowsOffset()) {\n  throw new IllegalArgumentException(\"limit+offset overflows; lower the limit or offset\");\n}","typeGuard":"boolean limitOffsetSafe(ScanQuery q) {\n  return !q.isLimited() || q.getScanRowsLimit() <= Long.MAX_VALUE - q.getScanRowsOffset();\n}","tryCatchPattern":"try {\n  chest.mergeResults(query, seq, responseContext);\n} catch (IllegalStateException e) {\n  if (e.getMessage().contains(\"due to overflow\")) { /* resubmit with clamped limit */ }\n  else throw e;\n}","preventionTips":["Never send Long.MAX_VALUE as scanRows limit together with an offset","Clamp limits in client SDKs before submission","Use explicit pagination (limit+offset) with bounded values"],"tags":["druid","scan-query","overflow","pagination"],"backgroundTag":"argument-out-of-range","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}