pola-rs/polars · error · ModuleUpgradeRequiredError

pyarrow>=8.0.0 is required for `to_pandas(use_pyarrow_extens

Error message

pyarrow>=8.0.0 is required for `to_pandas(use_pyarrow_extension_array=True)`, found pyarrow {pa.__version__!r}.

What it means

Raised as ModuleUpgradeRequiredError by DataFrame.to_pandas(use_pyarrow_extension_array=True) when pyarrow IS installed but its version is below 8.0.0. The pandas ArrowDtype/extension-array path relies on pyarrow features stabilized by 8.0, so polars checks `parse_version(pa.__version__) < (8, 0)` and appends the found version to the message. Distinct from the ModuleNotFoundError variant: here pyarrow exists, it is just too old.

Source

Thrown at py-polars/src/polars/dataframe/frame.py:2620

        2  <NA>   8.0     c
        >>> _.dtypes
        foo           int64[pyarrow]
        bar          double[pyarrow]
        ham    large_string[pyarrow]
        dtype: object
        """
        if self.width == 0:
            return pd.DataFrame(index=range(self.height))

        if use_pyarrow_extension_array:
            if parse_version(pd.__version__) < (1, 5):
                msg = f'pandas>=1.5.0 is required for `to_pandas("use_pyarrow_extension_array=True")`, found Pandas {pd.__version__!r}'
                raise ModuleUpgradeRequiredError(msg)
            if not _PYARROW_AVAILABLE or parse_version(pa.__version__) < (8, 0):
                msg = "pyarrow>=8.0.0 is required for `to_pandas(use_pyarrow_extension_array=True)`"
                if _PYARROW_AVAILABLE:
                    msg += f", found pyarrow {pa.__version__!r}."
                    raise ModuleUpgradeRequiredError(msg)
                else:
                    raise ModuleNotFoundError(msg)

        # handle Object columns separately (Arrow does not convert them correctly)
        if Object in self.dtypes:
            return self._to_pandas_with_object_columns(
                use_pyarrow_extension_array=use_pyarrow_extension_array, **kwargs
            )

        return self._to_pandas_without_object_columns(
            self, use_pyarrow_extension_array=use_pyarrow_extension_array, **kwargs
        )

    def _to_pandas_with_object_columns(
        self,
        *,
        use_pyarrow_extension_array: bool,
        **kwargs: Any,

View on GitHub (pinned to df599052da)

Solutions

  1. Upgrade pyarrow: `pip install -U 'pyarrow>=8'`
  2. If another package caps pyarrow below 8, upgrade that package or drop the extension-array flag (`df.to_pandas()`)
  3. Verify with `python -c "import pyarrow; print(pyarrow.__version__)"` after upgrading

Example fix

# before (pyarrow 7)
pdf = df.to_pandas(use_pyarrow_extension_array=True)  # ModuleUpgradeRequiredError

# after
# pip install -U 'pyarrow>=8'
pdf = df.to_pandas(use_pyarrow_extension_array=True)
Defensive patterns

Strategy: validation

Validate before calling

try:
    import pyarrow as pa
    pa_ok = parse_version(pa.__version__) >= (8, 0)
except ImportError:
    pa_ok = False

pdf = df.to_pandas(use_pyarrow_extension_array=True) if pa_ok else df.to_pandas()

Try / catch

try:
    pdf = df.to_pandas(use_pyarrow_extension_array=True)
except ModuleUpgradeRequiredError as e:
    if 'pyarrow>=8.0.0' in str(e) and 'found pyarrow' in str(e):
        pdf = df.to_pandas()
    else:
        raise

Prevention

When it happens

Trigger: `df.to_pandas(use_pyarrow_extension_array=True)` with pyarrow 7.x or older installed — common when another package (older pandas, ray, older duckdb) pinned a legacy pyarrow.

Common situations: Dependency resolver picking an old pyarrow to satisfy another package's upper bound; long-lived conda environments; air-gapped installs from stale wheels; mismatch between a freshly upgraded pandas and an old pyarrow.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/ea36b90da84c9746. Report an issue: GitHub.