bitwarden/server · error · BadRequestException

Range too large.

Error message

Range too large.

What it means

ApiHelpers.GetDateRange (used by the events/audit endpoints) defaults a null range to the last 30 days, swaps reversed start/end, then enforces a hard ceiling: the span must not exceed 367 days. A range wider than one year plus two days is rejected as HTTP 400.

Solutions

  1. Split the query into multiple paginated calls, each spanning no more than 367 days.
  2. Narrow the date-picker default range to <= 367 days.
  3. If you control the server, confirm 367 days is the intended cap before changing the constant.

Example fix

// before
GET /events?start=2023-01-01&end=2025-01-01
// after (page 1)
GET /events?start=2024-06-01&end=2024-12-01
Defensive patterns

Strategy: validation

Validate before calling

const MAX_RANGE_DAYS = 367;
function clampRange(start, end) {
  if (end - start > MAX_RANGE_DAYS * 86_400_000) {
    throw new Error(`Date range exceeds ${MAX_RANGE_DAYS} days; split the query.`);
  }
  return { start, end };
}

Type guard

function isWithinRangeLimit(start: Date, end: Date): boolean {
  return (end.getTime() - start.getTime()) <= 367 * 86_400_000;
}

Prevention

When it happens

Trigger: A GET /events (or any call site of GetDateRange) with `start` and `end` query parameters more than 367 days apart.

Common situations: Exporting a full audit/event history; a date picker defaulting to 'all time'; a client computing end-minus-start incorrectly (off-by-year); calendar widgets that round to year boundaries.

Related errors


AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13). Data as JSON: /api/errors/3f9453ed035e08e9. Report an issue: GitHub.

Appendix: source

Thrown at src/Api/Utilities/ApiHelpers.cs:102

    /// If a time span greater than 367 days is passed will throw BadRequestException.
    /// </remarks>
    public static Tuple<DateTime, DateTime> GetDateRange(DateTime? start, DateTime? end)
    {
        if (!end.HasValue || !start.HasValue)
        {
            end = DateTime.UtcNow.Date.AddDays(1).AddMilliseconds(-1);
            start = DateTime.UtcNow.Date.AddDays(-30);
        }
        else if (start.Value > end.Value)
        {
            var newEnd = start;
            start = end;
            end = newEnd;
        }

        if ((end.Value - start.Value) > TimeSpan.FromDays(367))
        {
            throw new BadRequestException("Range too large.");
        }

        return new Tuple<DateTime, DateTime>(start.Value, end.Value);
    }
}

View on GitHub (pinned to e93b962371)