{"record":{"id":"973fe7ffd85a6c3c","repo":"pandas-dev/pandas","slug":"cannot-supply-both-a-tz-and-a-timezone-naive-dtype","errorCode":null,"errorMessage":"cannot supply both a tz and a timezone-naive dtype (i.e. datetime64[ns])","messagePattern":"cannot supply both a tz and a timezone-naive dtype \\(i\\.e\\. datetime64\\[ns\\]\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/datetimes.py","lineNumber":3053,"sourceCode":"            except TypeError:\n                # Things like `datetime64[ns]`, which is OK for the\n                # constructors, but also nonsense, which should be validated\n                # but not by us. We *do* allow non-existent tz errors to\n                # go through\n                pass\n        dtz = getattr(dtype, \"tz\", None)\n        if dtz is not None:\n            if tz is not None and not timezones.tz_compare(tz, dtz):\n                raise ValueError(\"cannot supply both a tz and a dtype with a tz\")\n            if explicit_tz_none:\n                raise ValueError(\"Cannot pass both a timezone-aware dtype and tz=None\")\n            tz = dtz\n\n        if tz is not None and lib.is_np_dtype(dtype, \"M\"):\n            # We also need to check for the case where the user passed a\n            #  tz-naive dtype (i.e. datetime64[ns])\n            if tz is not None and not timezones.tz_compare(tz, dtz):\n                raise ValueError(\n                    \"cannot supply both a tz and a \"\n                    \"timezone-naive dtype (i.e. datetime64[ns])\"\n                )\n\n    return tz\n\n\ndef _infer_tz_from_endpoints(\n    start: Timestamp, end: Timestamp, tz: tzinfo | None\n) -> tzinfo | None:\n    \"\"\"\n    If a timezone is not explicitly given via `tz`, see if one can\n    be inferred from the `start` and `end` endpoints.  If more than one\n    of these inputs provides a timezone, require that they all agree.\n\n    Parameters\n    ----------\n    start : Timestamp","sourceCodeStart":3035,"sourceCodeEnd":3071,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/datetimes.py#L3035-L3071","documentation":"Raised by _validate_tz_from_dtype when a tz kwarg is supplied, the dtype is a numpy datetime64 ('M' kind, hence tz-naive), and the tz disagrees with the (None) dtype tz via timezones.tz_compare. The message names the specific case: the user passed both a tz kwarg and a tz-naive datetime64 dtype. Practically unreachable when tz is None, but fires for any non-None tz paired with a plain datetime64[ns] dtype that should have been a DatetimeTZDtype.","triggerScenarios":"Calling `pd.DatetimeIndex(values, dtype='datetime64[ns]', tz='UTC')` — the dtype string is tz-naive but a tz kwarg is also given. Functionally pandas will usually reconcile by adopting the tz kwarg, but in the conflict path (mismatched compare) it raises this.","commonSituations":"Code that simultaneously passes a fixed tz-naive default dtype and a tz kwarg with different intent. Migration where the dtype was hardcoded tz-naive and a tz kwarg was added later.","solutions":["Use a consistent representation: either drop the dtype and pass tz, or use a tz-aware dtype and drop the tz kwarg.","Prefer `pd.DatetimeIndex(values, tz='UTC')` and let pandas construct the right DatetimeTZDtype.","If the dtype is fixed upstream, strip the tz kwarg and let the dtype win."],"exampleFix":"// before\ndti = pd.DatetimeIndex(values, dtype='datetime64[ns]', tz='UTC')\n\n// after\ndti = pd.DatetimeIndex(values, tz='UTC')","handlingStrategy":"validation","validationCode":"import pandas as pd, numpy as np\n\ndef reconcile_np_m_dtype_with_tz(dtype_str, tz):\n    if dtype_str and tz is not None:\n        try:\n            d = pd.api.types.pandas_dtype(dtype_str)\n            if isinstance(d, np.dtype) and d.kind == 'M' and getattr(d, 'tz', None) is None:\n                return None, tz  # drop dtype, keep tz kwarg\n        except TypeError:\n            pass\n    return dtype_str, tz","typeGuard":"def no_tz_naive_np_m_with_tz(dtype_str, tz) -> bool:\n    import numpy as np, pandas as pd\n    if tz is None or not dtype_str:\n        return True\n    try:\n        d = pd.api.types.pandas_dtype(dtype_str)\n    except TypeError:\n        return True\n    return not (isinstance(d, np.dtype) and d.kind == 'M' and getattr(d, 'tz', None) is None)","tryCatchPattern":"try:\n    dti = pd.DatetimeIndex(values, dtype=dtype_str, tz=tz)\nexcept ValueError as e:\n    if 'timezone-naive dtype' in str(e):\n        dti = pd.DatetimeIndex(values, tz=tz)\n    else:\n        raise","preventionTips":["When passing tz as a kwarg, omit a tz-naive datetime64 dtype string.","Use pd.DatetimeTZDtype objects rather than ad-hoc dtype strings when tz matters."],"tags":["datetime","timezone","dtype","construction","validation"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}