pandas-dev/pandas · error · ValueError
Unexpected value for 'dtype
Error message
Unexpected value for 'dtype': '{dtype}'. Must be 'datetime64[s]', 'datetime64[ms]', 'datetime64[us]', 'datetime64[ns]' or DatetimeTZDtype'. What it means
Raised by _validate_dt64_dtype when the supplied dtype is a numpy dtype that is not an 'M' kind or is not a supported datetime resolution, OR is not a numpy.dtype / DatetimeTZDtype instance at all. The message enumerates the supported values. This is the catch-all dtype validation for datetime construction.
Solutions
- Verify the dtype string matches one of the supported forms exactly: 'datetime64[s]', 'datetime64[ms]', 'datetime64[us]', 'datetime64[ns]', or a DatetimeTZDtype like 'datetime64[ns, UTC]'.
- If the data is not yet datetime, first convert with `pd.to_datetime(values)` and only then specify a datetime dtype.
- If you wanted a non-datetime dtype, use `pd.Series` not `pd.DatetimeIndex`.
- For tz-aware targets, prefer constructing a DatetimeTZDtype object explicitly: `pd.DatetimeTZDtype(tz='UTC', unit='ns')`.
Example fix
// before dti = pd.DatetimeIndex(values, dtype='datetime64[n]') // after dti = pd.DatetimeIndex(values, dtype='datetime64[ns]')
Defensive patterns
Strategy: validation
Validate before calling
import pandas as pd
VALID = {'datetime64[s]', 'datetime64[ms]', 'datetime64[us]', 'datetime64[ns]'}
def is_supported_dt_dtype_string(s: str) -> bool:
if s in VALID:
return True
try:
return isinstance(pd.DatetimeTZDtype.construct_from_string(s), pd.DatetimeTZDtype)
except TypeError:
return False Type guard
import pandas as pd
def is_datetime_dtype_spec(s) -> bool:
try:
dt = pd.api.types.pandas_dtype(s)
except TypeError:
return False
return isinstance(dt, (np.dtype, pd.DatetimeTZDtype)) and (dt.kind == 'M' or isinstance(dt, pd.DatetimeTZDtype)) Try / catch
try:
dti = pd.DatetimeIndex(values, dtype=dtype_str)
except ValueError as e:
if "Unexpected value for 'dtype'" in str(e):
dti = pd.DatetimeIndex(values) # let pandas pick
else:
raise Prevention
- Whitelist supported datetime dtype strings in configuration surfaces.
- Prefer omitting dtype and letting pandas infer when in doubt.
When it happens
Trigger: Passing `dtype='int64'`, `dtype='float64'`, `dtype='object'`, `dtype='datetime64[fs]'` (unsupported unit), `dtype='category'`, or any non-datetime dtype to a DatetimeIndex/DatetimeArray constructor routed through _validate_dt64_dtype.
Common situations: Typo in a unit string (e.g. 'datetime64[n]'). Confusing a Series constructor (which accepts any dtype) with a DatetimeIndex constructor (which only accepts datetime dtypes). Programmatic code that passes whatever dtype a column currently has into a datetime-conversion call.
Related errors
- 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…
- Passing in 'datetime64' dtype with no precision is not…
- Passing PeriodDtype data is invalid. Use…
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/56abe5bc8b3a1611.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/datetimes.py:2988
-----
Unlike _validate_tz_from_dtype, this does _not_ allow non-existent
tz errors to go through
"""
if dtype is not None:
dtype = pandas_dtype(dtype)
if dtype == np.dtype("M8"):
# no precision, disallowed GH#24806
msg = (
"Passing in 'datetime64' dtype with no precision is not allowed. "
"Please pass in 'datetime64[ns]' instead."
)
raise ValueError(msg)
if (
isinstance(dtype, np.dtype)
and (dtype.kind != "M" or not is_supported_dtype(dtype))
) or not isinstance(dtype, (np.dtype, DatetimeTZDtype)):
raise ValueError(
f"Unexpected value for 'dtype': '{dtype}'. "
"Must be 'datetime64[s]', 'datetime64[ms]', 'datetime64[us]', "
"'datetime64[ns]' or DatetimeTZDtype'."
)
if getattr(dtype, "tz", None):
# https://github.com/pandas-dev/pandas/issues/18595
# Ensure that we have a standard timezone for pytz objects.
# Without this, things like adding an array of timedeltas and
# a tz-aware Timestamp (with a tz specific to its datetime) will
# be incorrect(ish?) for the array as a whole
dtype = cast("DatetimeTZDtype", dtype)
dtype = DatetimeTZDtype(
unit=dtype.unit, tz=timezones.tz_standardize(dtype.tz)
)
return dtype
View on GitHub (pinned to 3b7651241d)