You're trying to build a C extension, maybe a package like pandas or lxml from source, and boom — the compiler stops dead with fatal error: Python.h: No such file or directory. This usually hits right after you run pip install some-package or python setup.py build, and you're on a fresh Linux box or a macOS without the full dev tools. I know this error is infuriating because the Python interpreter runs fine, but the compiler can't find a header file. The root cause is simple: your system has Python installed, but not the development headers and static library that come in a separate package.
Here's the deal — Python ships in two flavors on most Linux distros: the runtime (python3) and the development files (python3-dev or python3-devel). The runtime includes the interpreter and standard library, but not the C headers like Python.h that live in /usr/include/python3.x/. When you compile a C extension, the compiler looks for those headers and the libpython library. If they're missing, you get this error.
The Fix: Install the Dev Headers
Skip the fiddling around — just install the package. The exact command depends on your OS.
On Debian/Ubuntu (apt)
- Open a terminal.
- Run:
sudo apt update - Then:
sudo apt install python3-dev
If you're using a specific Python version like 3.11, you can install python3.11-dev instead. But python3-dev matches your default Python 3.
On Fedora/RHEL/CentOS (dnf/yum)
- Run:
sudo dnf install python3-devel - Or on older systems:
sudo yum install python3-devel
On Arch Linux (pacman)
- Run:
— but that already includes headers; if not, trysudo pacman -S pythonpython-setuptools.
On macOS
macOS doesn't use apt, but the fix is similar — you need the Command Line Tools. The Python.h header is part of the system Python or the python.org installer's framework. If you're using the built-in Python, run:
xcode-select --install
That installs the Command Line Tools which include the necessary headers for the system Python. If you're using python.org's Python, make sure you checked "Install command line tools" during installation. Or use Homebrew: brew install python — that includes headers.
Still Failing? Check These
If you installed the dev package and the error persists, something else is off. Here's what I'd check in order:
- Is the header actually there? Look for the file:
ls /usr/include/python3.*/Python.h. If it's not there, the package didn't install properly. Reinstall it withsudo apt install --reinstall python3-dev. - Are you compiling against the right Python version? If you have multiple Pythons (e.g., 3.8 and 3.11), the compiler might be looking for headers for one version while you're building for another. Check which Python you're using with
which python3andpython3 --version. Then ensure the dev package matches that version. For example, if you're using 3.11 but only have 3.8-dev installed, you'll still get the error. - Virtual environment? If you're in a venv, it should still use the system headers. But if the venv was created with
--without-pipor something weird, it might not point to the right includes. Recreate the venv after installing the dev package. - Custom Python installation? If you compiled Python yourself from source, you might need to set
CPPFLAGSandLDFLAGSmanually. For instance, if Python is in/opt/python, export:
Then re-run your build.export CPPFLAGS="-I/opt/python/include/python3.11" export LDFLAGS="-L/opt/python/lib" - MacOS specific — if you're using the system Python and still get the error, ensure Xcode is fully installed (
xcode-select --installsometimes only installs a subset). Trysudo xcode-select --switch /Library/Developer/CommandLineToolsto point to the right path.
One more thing: if you're using a Docker container, you might need to install the headers inside the container, not on the host. And remember — after installing the package, restart your terminal or at least re-run the build command, because environment variables might not refresh automatically.
The real fix is almost always just installing the dev package. It's a classic beginner trap, and even pros trip on it when switching distros or after a fresh OS install. Now go compile that extension.