pandas-dev/pandas · error · ValueError

{freq=} is not supported

Error message

{freq=} is not supported

What it means

Raised by ArrowExtensionArray._round_temporally when the parsed offset's prefix is not in the supported mapping of pandas freq prefixes to pyarrow temporal units. Supported prefixes are Y, YS, Q, QS, M, MS, W, D, h, min, s, ms, us, ns. Business/custom offsets (e.g. 'B', 'SMS', 'CBM', 'BH') and any prefix outside that map hit ValueError. Reached through dt.ceil/floor/round on pyarrow timestamps.

Source

Thrown at pandas/core/arrays/arrow/array.py:4196

        pa_supported_unit = {
            "Y": "year",
            "YS": "year",
            "Q": "quarter",
            "QS": "quarter",
            "M": "month",
            "MS": "month",
            "W": "week",
            "D": "day",
            "h": "hour",
            "min": "minute",
            "s": "second",
            "ms": "millisecond",
            "us": "microsecond",
            "ns": "nanosecond",
        }
        unit = pa_supported_unit.get(offset._prefix, None)
        if unit is None:
            raise ValueError(f"{freq=} is not supported")
        multiple = offset.n
        rounding_method = getattr(pc, f"{method}_temporal")
        result = rounding_method(self._pa_array, multiple=multiple, unit=unit)
        return self._from_pyarrow_array(result)

    def _dt_ceil(
        self,
        freq,
        ambiguous: TimeAmbiguous = "raise",
        nonexistent: TimeNonexistent = "raise",
    ) -> Self:
        return self._round_temporally("ceil", freq, ambiguous, nonexistent)

    def _dt_floor(
        self,
        freq,
        ambiguous: TimeAmbiguous = "raise",
        nonexistent: TimeNonexistent = "raise",

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Round to a supported base unit then post-process for business logic, e.g. round to 'D' then snap to nearest business day with a custom offset.
  2. Cast to datetime64[ns] which supports business offsets via numpy path: `s.astype("datetime64[ns]").dt.floor("B")`.
  3. Use only plain unit prefixes: 'D','h','min','s','ms','us','ns' with an integer multiple.
  4. Switch to a non-anchored frequency that maps directly to a pyarrow temporal unit.

Example fix

# before
s.dt.floor("B")  # ValueError: B is not supported

# after: use numpy backend for business rounding
s.astype("datetime64[ns]").dt.floor("B")
Defensive patterns

Strategy: validation

Validate before calling

from pandas.tseries.frequencies import to_offset

SUPPORTED_PREFIXES = {"Y","YS","Q","QS","M","MS","W","D","h","min","s","ms","us","ns"}

def is_supported_freq(freq) -> bool:
    off = to_offset(freq)
    return off is not None and off._prefix in SUPPORTED_PREFIXES

def safe_round(s, freq, method="floor"):
    if not is_supported_freq(freq):
        raise ValueError(f"{freq!r} not supported by pyarrow rounding; use plain units")
    return s.dt.__getattribute__(method)(freq)

Type guard

from pandas.tseries.frequencies import to_offset

def is_supported_freq(freq) -> bool:
    off = to_offset(freq)
    return off is not None and off._prefix in {"Y","YS","Q","QS","M","MS","W","D","h","min","s","ms","us","ns"}

Try / catch

try:
    out = s.dt.floor(freq)
except ValueError as e:
    if "is not supported" in str(e):
        out = s.astype("datetime64[ns]").dt.floor(freq)
    else:
        raise

Prevention

When it happens

Trigger: Calling `s.dt.floor("B")` (business day), `s.dt.round("W-MON")` (anchored week), `s.dt.ceil("SMS")` (semi-month start), or any custom/business anchored frequency on a timestamp[pyarrow] Series.

Common situations: Financial/business calendars that rely on business-day rounding; reusing anchored freq strings from numpy-backed datetime code.

Related errors


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