Fix mysqlclient Install Errors (mysql_config not found)
Fix pip install mysqlclient failures for Django: mysql_config not found, pkg-config cannot find mysqlclient, and missing Python.h, on Ubuntu, Debian, RHEL, Alpine, macOS, and in Docker builds.
Problem statement
pip install mysqlclient or pip install -r requirements.txt fails during a server setup or Docker build:
Exception: Can not find valid pkg-config name.
Specify MYSQLCLIENT_CFLAGS and MYSQLCLIENT_LDFLAGS env vars manually
or the older OSError: mysql_config not found, or fatal error: Python.h: No such file or directory. mysqlclient is a C extension. When pip cannot find a pre-built wheel for your platform, it compiles from source and needs a compiler, Python headers, the MySQL or MariaDB client development library, and pkg-config to locate it. One of those is missing.
- Debian/Ubuntu:
sudo apt install python3-dev default-libmysqlclient-dev build-essential pkg-config. - RHEL/Rocky/Fedora:
sudo dnf install python3-devel mysql-devel gcc pkgconf-pkg-config(ormariadb-connector-c-devel). - Alpine:
apk add --no-cache build-base mariadb-dev pkgconfin the build stage,mariadb-connector-cat runtime. - macOS:
brew install mysql-client pkg-configand exportPKG_CONFIG_PATH. - In Docker, compile in a builder stage and copy the wheel or virtualenv into a slim runtime image.
Step-by-step solution
1. Read which piece is missing
Can not find valid pkg-config nameormysql_config not found→ client dev library orpkg-configmissing.Python.h: No such file or directory→ Python development headers missing.gcc: command not foundorx86_64-linux-gnu-gcc failed→ no compiler.
Since mysqlclient 2.2, pkg-config is used instead of mysql_config, so old instructions that only install the dev library may still fail without pkg-config.
2. Debian and Ubuntu
sudo apt update
sudo apt install -y python3-dev default-libmysqlclient-dev build-essential pkg-config
pip install mysqlclient
default-libmysqlclient-dev pulls in the MariaDB or MySQL client headers appropriate for the release. If your Python comes from deadsnakes or pyenv, install the matching headers, for example python3.12-dev.
3. RHEL, Rocky, Alma, Fedora
sudo dnf install -y gcc python3-devel pkgconf-pkg-config mariadb-connector-c-devel
pip install mysqlclient
With the MySQL community repository instead of MariaDB, use mysql-community-devel.
4. macOS for local development
brew install mysql-client pkg-config
export PKG_CONFIG_PATH="$(brew --prefix)/opt/mysql-client/lib/pkgconfig"
pip install mysqlclient
5. Docker: build in one stage, run in another
FROM python:3.12-slim AS build
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential default-libmysqlclient-dev pkg-config \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip wheel --wheel-dir /wheels -r requirements.txt
FROM python:3.12-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
libmariadb3 \
&& rm -rf /var/lib/apt/lists/*
COPY --from=build /wheels /wheels
RUN pip install --no-cache-dir /wheels/* && rm -rf /wheels
The runtime stage needs the shared library (libmariadb3 on current Debian) but not compilers or headers. If the app starts with ImportError: libmariadb.so.3: cannot open shared object file, the runtime library is missing.
6. Consider alternatives
If compiling is impractical (locked-down build environments, unusual platforms), Django also supports mysql-connector-python through its own backend, and PyMySQL can stand in via pymysql.install_as_MySQLdb(). Both are pure Python and slower; mysqlclient remains Django's recommended driver.
Verification check:
python -c "import MySQLdb; print(MySQLdb.version_info)"
python manage.py check --database default
Explanation
Pre-built wheels for mysqlclient exist for Windows, but on Linux the project historically relies on compiling against the system's MySQL or MariaDB client library, which varies by distribution. Pip therefore downloads the source distribution and runs a C build. The build script asks pkg-config for compiler and linker flags for mysqlclient or mariadb; without the .pc files that dev packages install, it cannot proceed. Separating build and runtime stages in Docker keeps images small while still compiling reliably.
Edge cases / notes
- Manual flags. In unusual environments set
MYSQLCLIENT_CFLAGSandMYSQLCLIENT_LDFLAGSyourself, as the error suggests. - ARM servers compile the same way; make sure the builder runs on the target architecture or use emulation.
- Lock files with hashes still build from source; caching wheels in CI saves minutes per build.
- Alpine uses musl; compiled wheels from Debian will not work there, and the reverse.
Next steps
- Configure the connection with Configure Django With MySQL in Production.
- The PostgreSQL equivalent is Fix psycopg Install Errors in Django.
FAQ
Why does pip compile mysqlclient instead of downloading it?
There is no pre-built Linux wheel for your platform, so pip builds from source and needs headers and a compiler.
Do I need the MySQL server installed?
No. Only the client development library is needed to build, and the client runtime library to run.
Can I use PyMySQL instead?
Yes, as a pure-Python fallback, but mysqlclient is faster and is Django's recommended driver.
Why does the container fail with libmariadb.so.3 missing?
The final image lacks the runtime client library. Install libmariadb3 in the runtime stage.