What is PEP 668?
If pip has ever refused with error: externally-managed-environment, that was PEP 668 at work.
PEP 668 (“Marking Python base environments as externally managed”) defines a mechanism for OS distributors to protect their Python installations from accidental modification by pip. Accepted in June 2022, it has since been adopted by major Linux distributions and by Homebrew on macOS.
Why it exists
Operating systems install Python packages into a shared site-packages directory. System tools depend on those packages being specific versions. Running pip install into that same directory can overwrite OS-managed files, breaking utilities like apt on Debian or dnf on Fedora. Before PEP 668, nothing stopped users from doing this by accident. For more background, see Why should I avoid using the system Python?.
How it works
A distribution places an EXTERNALLY-MANAGED marker file in the Python standard library directory (for example, /usr/lib/python3.12/EXTERNALLY-MANAGED). The file contains an [externally-managed] INI section with a custom error message from the distributor explaining what to do instead.
When pip detects this file, it refuses to install, uninstall, or upgrade packages in that environment. The error message directs users toward virtual environments or the system package manager.
The --break-system-packages flag overrides this protection. The same override is available as an environment variable: PIP_BREAK_SYSTEM_PACKAGES=1. Both should be used with caution, since they reintroduce the exact risks PEP 668 was designed to prevent.
Which platforms use it
Debian 12 (bookworm) and Ubuntu 23.04 were among the first to ship the marker. Homebrew’s Python formula on macOS followed. Most Debian-derived distributions now include it by default.
What to do instead
Create a virtual environment. The fastest path is uv:
$ uv init my-project
$ cd my-project
$ uv add requests
This creates an isolated environment where pip (or uv) can install packages without touching the system Python. See How to install Python with uv for a full walkthrough.
Learn More
Get Python tooling updates
Subscribe to the newsletter