{"record":{"id":"a1f8f402618328ed","repo":"apache/druid","slug":"cannot-apply-limit-d-with-offset-d-due-to-over","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","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/groupby/orderby/DefaultLimitSpec.java","lineNumber":323,"sourceCode":"  }\n\n  /**\n   * Returns a new DefaultLimitSpec identical to this one except for one difference: an offset parameter, if any, will\n   * be removed and added to the limit. This is designed for passing down queries to lower levels of the stack. Only\n   * the highest level should apply the offset parameter, and any pushed-down limits must be increased to accommodate\n   * the offset.\n   */\n  public DefaultLimitSpec withOffsetToLimit()\n  {\n    if (isOffset()) {\n      final int newLimit;\n\n      if (limit == Integer.MAX_VALUE) {\n        // Unlimited stays unlimited.\n        newLimit = Integer.MAX_VALUE;\n      } else if (limit > Integer.MAX_VALUE - offset) {\n        // Handle overflow as best we can.\n        throw new ISE(\"Cannot apply limit[%d] with offset[%d] due to overflow\", limit, offset);\n      } else {\n        newLimit = limit + offset;\n      }\n\n      return new DefaultLimitSpec(columns, 0, newLimit);\n    } else {\n      return this;\n    }\n  }\n\n  private Ordering<ResultRow> makeComparator(\n      RowSignature rowSignature,\n      boolean hasTimestamp,\n      List<DimensionSpec> dimensions,\n      List<AggregatorFactory> aggs,\n      List<PostAggregator> postAggs,\n      boolean sortByDimsFirst\n  )","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/groupby/orderby/DefaultLimitSpec.java#L305-L341","documentation":"DefaultLimitSpec.withOffsetToLimit rewrites a limit spec with an offset into an equivalent spec with offset 0 and limit = limit + offset. If that sum would exceed Integer.MAX_VALUE, the rewrite would overflow int arithmetic, so it deliberately throws an IllegalStateException instead of silently wrapping.","triggerScenarios":"Calling withOffsetToLimit on a DefaultLimitSpec whose combined limit + offset exceeds Integer.MAX_VALUE (e.g. limit near Integer.MAX_VALUE plus a positive offset); invoked during query planning when converting offsets to limits.","commonSituations":"Users setting huge limits like 2147483647 plus an offset for 'all rows' semantics; programmatic limit construction with sentinel MAX_VALUE values; pagination helpers that add offsets to unbounded limits.","solutions":["Use a smaller limit so limit + offset stays within Integer.MAX_VALUE.","Model 'unlimited' as limit = Integer.MAX_VALUE with offset 0 rather than adding offsets to MAX_VALUE.","Guard the offset application in caller code: only call withOffsetToLimit when (long)limit + offset <= Integer.MAX_VALUE."],"exampleFix":"// before\nnew DefaultLimitSpec(columns, offset, Integer.MAX_VALUE).withOffsetToLimit(offset)\n// after\nint limit = limitSpec.getLimit() == Integer.MAX_VALUE ? Integer.MAX_VALUE : limitSpec.getLimit() - offset;","handlingStrategy":"validation","validationCode":"if (limit != Integer.MAX_VALUE && (long) limit + offset > Integer.MAX_VALUE) {\n  throw new IllegalArgumentException(\"limit+offset overflows int\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  return spec.withOffsetToLimit(offset);\n} catch (IllegalStateException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"due to overflow\")) {\n    return new DefaultLimitSpec(spec.getColumns(), 0, Integer.MAX_VALUE);\n  }\n  throw e;\n}","preventionTips":["Compute limit+offset in long before constructing limit specs","Represent 'unlimited' as MAX_VALUE with offset 0, never as MAX_VALUE plus offset","Cap user-supplied pagination limits in the API layer"],"tags":["druid","limit-spec","integer-overflow","pagination"],"backgroundTag":"value-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"}