pandas-dev/pandas · error · OutOfBoundsTimedelta

overflow in timedelta operation

Error message

overflow in timedelta operation

What it means

Raised by _check_cumsum_overflow (datetimelike_accumulations.py:50) as OutOfBoundsTimedelta when a cumsum on a timedelta64 or datetime64 array would overflow int64. Internally these arrays are stored as int64 nanosecond ticks; cumsum is computed in i8 space. _check_cumsum_overflow detects when a positive addend produced a non-increasing total (a signed wrap) or landed exactly on the NaT sentinel iNaT, which would corrupt the result, so pandas refuses to return a misleading value.

Source

Thrown at pandas/core/array_algos/datetimelike_accumulations.py:50

    mask : np.ndarray[bool]
        Positions whose result will be NaT regardless, and so are exempt.
    """
    # Whether each running total is greater than the one before it, taking the
    #  total before the first entry to be zero.
    stepped_up = np.empty(result.shape, dtype=bool)
    np.greater(result[:1], 0, out=stepped_up[:1])
    np.greater(result[1:], result[:-1], out=stepped_up[1:])

    # Absent a signed wrap, the total goes up exactly when the addend is
    #  positive; a wrap flips the direction of the step.
    invalid = (values > 0) != stepped_up
    # A total of exactly int64.min does not wrap, but is indistinguishable
    #  from NaT once stored.
    invalid |= result == iNaT
    invalid &= ~mask

    if invalid.any():
        raise OutOfBoundsTimedelta("overflow in timedelta operation")


def _cum_func(
    func: Callable,
    values: np.ndarray,
    *,
    skipna: bool = True,
) -> np.ndarray:
    """
    Accumulations for 1D datetimelike arrays.

    Parameters
    ----------
    func : np.cumsum, np.maximum.accumulate, np.minimum.accumulate
    values : np.ndarray
        Numpy array with the values (can be of any dtype that support the
        operation). Values is changed is modified inplace.
    skipna : bool, default True

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Reduce the magnitude before cumsum: convert timedelta to a coarser unit (e.g. .dt.total_seconds() or astimeunit) and track overflow at that granularity.
  2. Skip the offending rows or downsample/aggregate so the running total stays within int64 ns range.
  3. Compute cumsum on a plain int64 Series of your chosen unit and cast back to timedelta64 only at the end (or never, if you can keep it as int).

Example fix

// before
s = pd.Series(pd.to_timedelta(np.full(10_000, 10**17), unit='ns'))
s.cumsum()  # overflow
// after
secs = s.dt.total_seconds()
(secs.cumsum() * 1e9).astype('timedelta64[ns]')
Defensive patterns

Strategy: try-catch

Validate before calling

import numpy as np
ns = s.astype('i8') if hasattr(s, 'dtype') and s.dtype.kind in 'mM' else s
running = np.cumsum(np.asarray(ns))
stepped_up = np.empty(running.shape, dtype=bool)
np.greater(running[:1], 0, out=stepped_up[:1])
np.greater(running[1:], running[:-1], out=stepped_up[1:])
if ((ns > 0) != stepped_up).any():
    raise OverflowError('cumsum would overflow int64 ns; reduce magnitude or change unit')

Try / catch

from pandas._libs.tslibs import OutOfBoundsTimedelta
try:
    s.cumsum()
except OutOfBoundsTimedelta:
    # fall back to a coarser unit
    (s.dt.total_seconds().cumsum() * 1e9).astype('timedelta64[ns]')

Prevention

When it happens

Trigger: Calling Series.cumsum() (or df.cumsum()) on a timedelta64 Series whose running total exceeds the int64 nanosecond range (~292 years), or on a datetime64 cumulative sum. Triggered at datetimelike_accumulations.py:43-50 when (values > 0) != stepped_up or result == iNaT after np.cumsum in i8 space.

Common situations: Aggregating long sequences of large timedeltas (e.g. hours/days cumulated over millions of rows); summing durations that span more than ~292 years; converting large integer counts of days to timedelta then cumsumming; loading wide time-series data.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/9188262671e25463. Report an issue: GitHub.