pandas-dev/pandas · error · ValueError
Passed data is timezone-aware, incompatible with 'tz=None'…
Error message
Passed data is timezone-aware, incompatible with 'tz=None'. Use obj.tz_localize(None) instead.
What it means
Raised by DatetimeArray._sequence_to_dt64 path when the supplied data is timezone-aware (a tz was inferred or present) but the caller explicitly requested tz=None. tz=None is ambiguous here — it could mean 'drop tz' or 'no tz expected' — so pandas makes the user choose with tz_localize(None), avoiding silent data loss.
Solutions
- Drop the timezone intentionally: obj.tz_localize(None) before construction.
- Preserve the timezone by passing the correct tz= explicitly.
- If you want naive UTC values, obj.tz_convert('UTC').tz_localize(None).
Example fix
// before
aware = pd.Series(pd.to_datetime(['2020-01-01']).tz_localize('UTC'))
pd.DatetimeIndex(aware, tz=None) # ValueError: tz-aware incompatible with tz=None
// after
pd.DatetimeIndex(aware).tz_localize(None) # explicitly drop tz Defensive patterns
Strategy: validation
Validate before calling
def build_index(values, tz=None):
inferred_tz = getattr(values.dtype, "tz", None)
if inferred_tz is not None and tz is None:
raise ValueError("data is tz-aware; call tz_localize(None) to drop")
return pd.DatetimeIndex(values, tz=tz) Type guard
def is_tz_aware(values) -> bool:
return getattr(getattr(values, "dtype", None), "tz", None) is not None Try / catch
try:
idx = pd.DatetimeIndex(aware, tz=None)
except ValueError as e:
if "tz=None" in str(e):
idx = pd.DatetimeIndex(aware).tz_localize(None)
else:
raise Prevention
- Never pass tz=None against tz-aware data; pass the explicit tz or call tz_localize.
- Track tz state through your pipeline explicitly rather than defaulting to None.
- Unit-test the tz-aware code path.
When it happens
Trigger: pd.DatetimeIndex(tz_aware_series, tz=None); pd.to_datetime(tz_aware_values, tz=None) is not the trigger here, but internal/array construction with explicit_tz_none=True against tz-aware data is; constructing Series/Index where the dtype or call signature forces tz=None.
Common situations: Passing an already-localized column into a constructor that defaults tz to None; refactoring code that previously used the old silent-drop behavior; mixing tz-aware sources in a pipeline that explicitly nulls tz.
Related errors
- Already tz-aware, use tz_convert to convert.
- Cannot convert tz-naive timestamps, use tz_localize to…
- Cannot pass both a timezone-aware dtype and tz=None
- cannot supply both a tz and a dtype with a tz
- cannot supply both a tz and a timezone-naive dtype (i.e…
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/603519693106c30e.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/datetimes.py:371
unit = dtl.dtype_to_unit(dtype)
data, copy = dtl.ensure_arraylike_for_datetimelike(
data, copy, cls_name="DatetimeArray"
)
subarr, tz = _sequence_to_dt64(
data,
copy=copy,
tz=tz,
dayfirst=dayfirst,
yearfirst=yearfirst,
ambiguous=ambiguous,
out_unit=unit,
)
# We have to call this again after possibly inferring a tz above
_validate_tz_from_dtype(dtype, tz, explicit_tz_none)
if tz is not None and explicit_tz_none:
raise ValueError(
"Passed data is timezone-aware, incompatible with 'tz=None'. "
"Use obj.tz_localize(None) instead."
)
data_unit = np.datetime_data(subarr.dtype)[0]
data_unit = cast("TimeUnit", data_unit)
data_dtype = tz_to_dtype(tz, data_unit)
result = cls._simple_new(subarr, dtype=data_dtype)
if unit is not None and unit != result.unit:
# If unit was specified in user-passed dtype, cast to it here
# error: Argument 1 to "as_unit" of "TimelikeOps" has
# incompatible type "str"; expected "Literal['s', 'ms', 'us', 'ns']"
# [arg-type]
result = result.as_unit(unit) # type: ignore[arg-type]
return result
@classmethodView on GitHub (pinned to 3b7651241d)