Skip to content

[Bug]: Large duration values in seconds/minutes/hours fail to calculate correct reset times due to day rollover bug #17993

@jasonpnnl

Description

@jasonpnnl

What happened?

Bug Description

The get_next_standardized_reset_time() function in litellm/litellm_core_utils/duration_parser.py has a critical bug that causes incorrect budget reset time calculations when large duration values are specified in seconds, minutes, or hours. The bug affects _handle_second_reset(), _handle_minute_reset(), and _handle_hour_reset() functions.

Problem

When calculating reset times for durations that span multiple days, these functions only add 1 day to the reset time regardless of how many days the duration actually spans. This causes budget resets to be scheduled far too early.

Example Scenario

Working correctly:

  • budget_duration: "365d" → Correctly calculates reset time 365 days in the future

Broken:

  • budget_duration: "31536000s" (1 year in seconds) → Incorrectly calculates reset time ~1 day in the future instead of 365 days

Root Cause

In _handle_second_reset() (lines 318-364):

# Calculate next second aligned with the value
# ... calculation logic ...

# Handle overnight case
if next_hour >= 24:
    next_hour = next_hour % 24
    next_day = base_midnight + timedelta(days=1)  # BUG: Only adds 1 day!
    return next_day.replace(
        hour=next_hour, minute=next_minute, second=next_second, microsecond=0
    )

When value is large (e.g., 31,536,000 seconds), next_hour will be an enormous number. The code wraps it with % 24 but then only adds timedelta(days=1) instead of calculating the actual number of days.

Same Bug Exists In:

  1. _handle_minute_reset() (lines 306-311):

    if next_hour >= 24:
        next_hour = next_hour % 24
        next_day = base_midnight + timedelta(days=1)  # BUG
  2. _handle_hour_reset() (lines 266-269):

    if next_hour >= 24:
        next_hour = next_hour % 24
        next_day = base_midnight + timedelta(days=1)  # BUG

Proposed Fix

Calculate the actual number of days from the hour overflow:

For _handle_second_reset():

# Handle overnight case
if next_hour >= 24:
    extra_days = next_hour // 24
    next_hour = next_hour % 24
    next_day = base_midnight + timedelta(days=extra_days)
    return next_day.replace(
        hour=next_hour, minute=next_minute, second=next_second, microsecond=0
    )

For _handle_minute_reset():

# Handle overnight case
if next_hour >= 24:
    extra_days = next_hour // 24
    next_hour = next_hour % 24
    next_day = base_midnight + timedelta(days=extra_days)
    return next_day.replace(
        hour=next_hour, minute=next_minute, second=0, microsecond=0
    )

For _handle_hour_reset():

# Handle overnight case
if next_hour >= 24:
    extra_days = next_hour // 24
    next_hour = next_hour % 24
    next_day = base_midnight + timedelta(days=extra_days)
    return next_day.replace(hour=next_hour)

Impact

This bug affects:

  • Budget management: Keys/users/teams with large budget_duration values in seconds/minutes/hours will have their budgets reset far too frequently
  • Cost control: Organizations relying on long-term budget resets (e.g., annual budgets) could experience unexpected resets
  • API key management: Keys with long validity periods specified in non-day units will expire prematurely

Comparison with Working Code

The _handle_day_reset() function correctly handles this case (lines 232-235):

else:  # Custom day value - next interval is value days from current
    return current_time.replace(
        hour=0, minute=0, second=0, microsecond=0
    ) + timedelta(days=value)  # ✓ Correctly adds all days

Workaround

Until fixed, users should specify large durations using days ("365d") rather than equivalent values in seconds ("31536000s"), minutes ("525600m"), or hours ("8760h").

Environment

  • File: litellm/litellm_core_utils/duration_parser.py
  • Functions affected: _handle_second_reset(), _handle_minute_reset(), _handle_hour_reset()
  • Version: Latest (as of December 2025)

Severity

High - This bug can cause significant issues with budget management and cost controls in production environments when large duration values are used.

Relevant log output

Are you a ML Ops Team?

No

What LiteLLM version are you on ?

v1.80.10.rc.2

Twitter / LinkedIn details

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions