Paul's Programming Notes PostsRSSGithub

src/pycurl.c:42:20: fatal error: Python.h: No such file or directory

Updated 2026-08-08: explained why the header is missing and updated the package names for Python 3.

The following helped to resolve this issue: sudo apt-get install python-dev

On a current machine that package is python3-dev:

sudo apt-get install python3-dev

The confusing part is that Python is obviously installed already, or pip wouldn’t have gotten far enough to run a compiler. pycurl is a C extension wrapping libcurl, so pip builds it from source, and building any CPython extension means compiling against Python.h. That header ships in a separate development package rather than with the interpreter, which is why a working python3 gives you no headers at all. Red Hat and Fedora call it python3-devel.

Being inside a virtualenv doesn’t change this. The venv copies the interpreter but not the headers, so the system package is still what the compile needs.

The next error after this one is usually curl/curl.h: No such file or directory, which is the same problem one library over. libcurl’s headers come from libcurl4-openssl-dev on Debian and Ubuntu, or libcurl-devel on Red Hat. pycurl’s install docs list the rest of the build requirements.

The trap after that one doesn’t show up until import, so it’s easy to think the build succeeded:

pycurl: libcurl link-time ssl backend (openssl) is different from compile-time ssl backend

pycurl has to be built against the same TLS library its libcurl uses, and it guesses wrong on a machine carrying more than one. The first line of curl -V names the library to match:

PYCURL_SSL_LIBRARY=openssl pip install --no-cache-dir pycurl

--no-cache-dir matters, because pip will otherwise hand back the same wrongly-built wheel it cached on the previous attempt.