Skip to content
Latchkey

Python "ModuleNotFoundError: No module named 'distutils'" in CI

Python 3.12 removed the standard-library distutils. Code or a build backend that still imports it fails on 3.12+ unless setuptools (which now vendors distutils) is installed and recent.

What this error means

On Python 3.12 or newer, a build or import fails with ModuleNotFoundError: No module named 'distutils'. The same code works on 3.11 where distutils still ships in the stdlib.

Python traceback
Traceback (most recent call last):
  File "setup.py", line 1, in <module>
    from distutils.core import setup
ModuleNotFoundError: No module named 'distutils'

Common causes

distutils removed in Python 3.12

Per PEP 632, distutils left the standard library in 3.12. Anything importing it directly breaks unless a vendored copy is provided.

Old setuptools not providing the shim

Recent setuptools vendors distutils and registers it on import. An outdated setuptools (or none) means the import has nothing to resolve to.

How to fix it

Upgrade setuptools

Modern setuptools provides distutils on 3.12+. Upgrade it first.

Terminal
python -m pip install --upgrade pip setuptools

Install the distro distutils for the legacy path

On Debian/Ubuntu with an older Python that split it out, install the package.

Terminal
apt-get update && apt-get install -y python3-distutils

How to prevent it

  • Upgrade setuptools early in CI so the distutils shim is present.
  • Migrate setup.py off direct distutils imports.
  • Pin Python deliberately when adopting 3.12+ so build tooling is ready.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →