pandas-dev/pandas · error · ValueError
Cannot pass both a timezone-aware dtype and tz=None
Error message
Cannot pass both a timezone-aware dtype and tz=None
What it means
Raised by _validate_tz_from_dtype when the dtype carries a tz (dtz is not None) and the caller explicitly passed `tz=None` (signaled by the explicit_tz_none flag, set when the user wrote tz=None literally rather than omitting it). This catches the contradictory request 'aware dtype but explicitly no tz'.
Solutions
- Drop the explicit `tz=None` and let the dtype's tz win.
- If you genuinely want a tz-naive result, also pass a tz-naive dtype like 'datetime64[ns]'.
- In library wrappers, treat `tz is None` as 'use dtype tz' (don't forward None literally when dtype carries tz).
Example fix
// before dti = pd.DatetimeIndex(values, dtype='datetime64[ns, UTC]', tz=None) // after dti = pd.DatetimeIndex(values, dtype='datetime64[ns, UTC]')
Defensive patterns
Strategy: validation
Validate before calling
import pandas as pd
def drop_explicit_none(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 None:
return dtype_str, 'omit' # do not forward tz=None
return dtype_str, tz Type guard
def explicit_none_safe(dtype_str, explicit_tz_none) -> 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
return not (dtz is not None and explicit_tz_none) Try / catch
try:
dti = pd.DatetimeIndex(values, dtype=dtype_str, tz=tz)
except ValueError as e:
if 'timezone-aware dtype and tz=None' in str(e):
kwargs = {'dtype': dtype_str}
if tz is not None:
kwargs['tz'] = tz
dti = pd.DatetimeIndex(values, **kwargs)
else:
raise Prevention
- Treat `tz is None` as 'unset' and do not forward it literally when dtype carries tz.
- Document tz=None semantics clearly in wrapper APIs.
When it happens
Trigger: Calling `pd.DatetimeIndex(values, dtype='datetime64[ns, UTC]', tz=None)` — the literal tz=None conflicts with the tz embedded in the dtype. Reached when library code forwards a user-supplied tz=None alongside a tz-aware dtype.
Common situations: Wrapper functions that pass `tz=tz` where tz defaults to None, combined with a tz-aware default dtype. Refactoring that introduced explicit_tz_none semantics (older pandas would silently drop).
Related errors
- cannot supply both a tz and a dtype with a tz
- cannot supply both a tz and a timezone-naive dtype (i.e…
- Unexpected value for 'dtype
- Cannot use .astype to convert from timezone-aware dtype to…
- data is already tz-aware
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/b39df205f616898d.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/datetimes.py:3046
------
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
) -> tzinfo | None:
"""View on GitHub (pinned to 3b7651241d)