pandas-dev/pandas · error · ValueError

cannot supply both a tz and a dtype with a tz

Error message

cannot supply both a tz and a dtype with a tz

What it means

Raised by _validate_tz_from_dtype when a tz argument is supplied AND the dtype itself carries a tz (DatetimeTZDtype) AND the two disagree per timezones.tz_compare. The function refuses to silently prefer one over the other; you must reconcile them. Note this branch checks `dtz is not None` (dtype has tz) and the conflict is between the kwarg tz and the dtype tz.

Solutions

  1. Supply the tz through exactly one channel: either embed it in the dtype string OR pass it as the tz kwarg, not both.
  2. If both are needed by API contract, ensure they agree: `assert tz is None or tz_compare(tz, dtype.tz)`.
  3. Prefer the tz kwarg and use a tz-naive dtype like 'datetime64[ns]' to avoid duplication.

Example fix

// before
dti = pd.DatetimeIndex(values, dtype='datetime64[ns, US/Eastern]', tz='US/Pacific')

// after
dti = pd.DatetimeIndex(values, tz='US/Pacific')
Defensive patterns

Strategy: validation

Validate before calling

import pandas as pd

def single_tz_channel(dtype_str, tz):
    dtz = None
    if dtype_str:
        try:
            d = pd.DatetimeTZDtype.construct_from_string(dtype_str)
            dtz = getattr(d, 'tz', None)
        except TypeError:
            pass
    if dtz is not None and tz is not None:
        return dtype_str, None  # prefer dtype, drop tz kwarg
    return dtype_str, tz

Type guard

def tz_channels_agree(dtype_str, tz) -> bool:
    import pandas as pd
    dtz = None
    if dtype_str:
        try:
            d = pd.DatetimeTZDtype.construct_from_string(dtype_str)
            dtz = getattr(d, 'tz', None)
        except TypeError:
            pass
    if dtz is None or tz is None:
        return True
    return pd.core.dtypes.common.timezones.tz_compare(dtz, tz)

Try / catch

try:
    dti = pd.DatetimeIndex(values, dtype=dtype_str, tz=tz)
except ValueError as e:
    if 'cannot supply both a tz and a dtype' in str(e):
        dti = pd.DatetimeIndex(values, tz=tz)
    else:
        raise

Prevention

When it happens

Trigger: Calling `pd.DatetimeIndex(values, dtype='datetime64[ns, US/Eastern]', tz='US/Pacific')` — both channels specify a tz and they differ. Constructing a Series/Index where the dtype string embeds one tz and a separate tz kwarg supplies another.

Common situations: Building dtype strings dynamically and also passing a tz kwarg as a 'safety net'. Refactoring that left both forms in place. Mixing a hardcoded tz kwarg with a parameterized dtype string.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/10eeed4c42c7c3d2. Report an issue: GitHub.

Appendix: source

Thrown at pandas/core/arrays/datetimes.py:3044

    Raises
    ------
    ValueError : on tzinfo mismatch
    """
    if dtype is not None:
        if isinstance(dtype, str):
            try:
                dtype = DatetimeTZDtype.construct_from_string(dtype)
            except TypeError:
                # Things like `datetime64[ns]`, which is OK for the
                # constructors, but also nonsense, which should be validated
                # but not by us. We *do* allow non-existent tz errors to
                # go through
                pass
        dtz = getattr(dtype, "tz", None)
        if dtz is not None:
            if tz is not None and not timezones.tz_compare(tz, dtz):
                raise ValueError("cannot supply both a tz and a dtype with a tz")
            if explicit_tz_none:
                raise ValueError("Cannot pass both a timezone-aware dtype and tz=None")
            tz = dtz

        if tz is not None and lib.is_np_dtype(dtype, "M"):
            # We also need to check for the case where the user passed a
            #  tz-naive dtype (i.e. datetime64[ns])
            if tz is not None and not timezones.tz_compare(tz, dtz):
                raise ValueError(
                    "cannot supply both a tz and a "
                    "timezone-naive dtype (i.e. datetime64[ns])"
                )

    return tz


def _infer_tz_from_endpoints(
    start: Timestamp, end: Timestamp, tz: tzinfo | None

View on GitHub (pinned to 3b7651241d)