pandas-dev/pandas · error · OutOfBoundsTimedelta

Overflow in timedelta multiplication

Error message

Overflow in timedelta multiplication

What it means

Raised by TimedeltaArray._mul_float_overflowsafe when a float multiplication of the int64 nanosecond ticks would produce a magnitude >= 2**63, exceeding the int64 range. The check (GH#43178) compares max(abs(non_nan)) against 2.0**63 (not i8max) to catch values that would round up to 2**63 in float64 and silently saturate on the i8 cast. It is raised as OutOfBoundsTimedelta to match pandas' other td64 overflow paths.

Source

Thrown at pandas/core/arrays/timedeltas.py:477

    def _mul_float_overflowsafe(
        self, other: float | np.floating | npt.NDArray[np.floating]
    ) -> Self:
        # GH#43178: detect float products that would silently saturate to
        #  int64.max on the int64 cast below
        i8 = self.asi8
        self_mask = i8 == iNaT
        if self_mask.any():
            # zero out NaT positions so they don't trigger the bounds check
            i8 = np.where(self_mask, 0, i8)
        f_result = i8 * other
        nan_mask = np.isnan(f_result)
        non_nan = f_result[~nan_mask]
        # Compare against 2**63, not i8max: i8max (2**63 - 1) rounds up to
        #  2**63 in float64, so a product landing exactly on 2**63 would slip
        #  past a ``> i8max`` check and saturate on the cast. Also catches +/-inf.
        if non_nan.size and np.max(np.abs(non_nan), initial=0.0) >= 2.0**63:
            raise OutOfBoundsTimedelta("Overflow in timedelta multiplication")
        # NaN-to-int cast is platform-dependent; substitute 0 then re-mask as NaT
        if nan_mask.any():
            f_result = np.where(nan_mask, 0.0, f_result)
        i8_result = f_result.astype("i8")
        nat_out = self_mask | nan_mask
        if nat_out.any():
            i8_result[nat_out] = iNaT
        result = i8_result.view(self._ndarray.dtype)
        return type(self)._simple_new(result, dtype=result.dtype)

    def _mul_int_overflowsafe(self, i8_other: npt.NDArray[np.int64]) -> Self:
        # GH#43178: mul_overflowsafe raises the low-level OverflowError; surface
        #  it as OutOfBoundsTimedelta to match pandas' other td64 overflow paths.
        try:
            i8_result = mul_overflowsafe(self.asi8, i8_other)
        except OverflowError as err:
            raise OutOfBoundsTimedelta("Overflow in int64 multiplication") from err
        result = i8_result.view(self._ndarray.dtype)

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Reduce the magnitude before multiplying: convert the array to a coarser supported unit via astype first.
  2. Use a smaller multiplier and adjust units (e.g. multiply seconds, not nanoseconds).
  3. Operate in Python decimals/objects if true large-magnitude products are required, then re-wrap carefully.

Example fix

# before
(td_arr * 1e9)  # OutOfBoundsTimedelta if td_arr in ns
# after
td_arr.astype('timedelta64[s]') * 1e9
Defensive patterns

Strategy: validation

Validate before calling

I8_MAX_NS = 2**63

def safe_float_mul(td_arr, factor):
    peak = td_arr.asi8.max() * abs(factor)
    if peak >= I8_MAX_NS:
        td_arr = td_arr.astype('timedelta64[s]')
    return td_arr * factor

Type guard

import numpy as np
def float_mul_will_overflow(td_arr, factor) -> bool:
    return np.max(np.abs(td_arr.asi8)) * abs(factor) >= 2**63

Try / catch

from pandas.errors import OutOfBoundsTimedelta
try:
    return td_arr * factor
except OutOfBoundsTimedelta as e:
    if 'Overflow in timedelta multiplication' in str(e):
        return td_arr.astype('timedelta64[s]') * factor
    raise

Prevention

When it happens

Trigger: Multiplying a large-magnitude timedelta64 array by a large float, e.g. `td_arr * 1e9` where td_arr values are already days. The bound check at timedeltas.py:476 triggers when the float product exceeds 2**63.

Common situations: Unit conversion helpers that multiply instead of using astype; scaling durations by large factors; feeding raw nanosecond ints through float math.

Related errors


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