Fix: error externally-managed-environment (pip)

Why pip says externally-managed-environment (PEP 668) and how to fix it: use a virtual environment, pipx or uv, the OS package, or —break-system-packages.

The fix is to stop installing into the system Python: create a virtual environment and run pip install inside it. The error is a safety feature defined in PEP 668, not a bug in pip.

What the error looks like

This is the output on Ubuntu 24.04 with its system Python 3.12.3 and pip 24.0:

$ python3.12 -m pip install requests
error: externally-managed-environment

× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
    python3-xyz, where xyz is the package you are trying to
    install.

    If you wish to install a non-Debian-packaged Python package,
    create a virtual environment using python3 -m venv path/to/venv.
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
    sure you have python3-full installed.

    If you wish to install a non-Debian packaged Python application,
    it may be easiest to use pipx install xyz, which will manage a
    virtual environment for you. Make sure you have pipx installed.

    See /usr/share/doc/python3.12/README.venv for more information.

note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.

The middle section is written by the distributor, so other systems show different advice. pip install --user fails with the same error.

Why it happens

Linux distributions use Python for their own tools. Installing a package with pip into that Python can conflict with a library the operating system depends on. The PyPA specification lets a distributor mark an interpreter by putting a file called EXTERNALLY-MANAGED in its standard library directory. Before installing, an installer checks two things: that it is running outside a virtual environment, and that the marker file exists. If both are true it stops with an error. The mechanism is opt-in, so an interpreter compiled from upstream sources or from a distro that has not marked it works as it always has.

You can run the same check yourself:

import sys, sysconfig
from pathlib import Path

marker = Path(sysconfig.get_path("stdlib", sysconfig.get_default_scheme())) / "EXTERNALLY-MANAGED"
print(marker, "exists =", marker.exists(), "in a venv =", sys.prefix != sys.base_prefix)
PythonMarker fileResult
Ubuntu 24.04 system Python 3.12Presentpip refuses to install
A Python installed by uv python installPresentpip and uv refuse
Python built from source in /usr/localAbsentpip installs normally
A virtual environment created from any of theseNot checkedpip installs normally

Homebrew’s Python formulae also write the marker, and its formula for Python 3.13 carries a comment saying it marks Homebrew’s Python as externally managed. The PyPA specification’s own example marker file is Debian’s.

Fix 1: a virtual environment (the right answer)

python3 -m venv .venv
source .venv/bin/activate
pip install requests

This was run against the same Ubuntu system Python and installs requests into .venv with no error. If python3 -m venv fails on a Debian-based system, install the package the error message names, python3-full. The environment is private to your project, so nothing can clash with the system. For the full explanation, see Python virtual environments explained.

Fix 2: use uv

uv creates the environment for you:

uv venv
uv pip install requests
# or, in a project
uv add requests

uv follows the same rule. uv pip install --system --python /usr/bin/python3.12 requests fails with The interpreter at /usr is externally managed and prints the distro’s message, and installing into a Python that uv itself downloaded fails with This Python installation is managed by uv and should not be modified, plus a hint to create a virtual environment with uv venv. Pointing uv at the system Python to create a virtual environment works: uv venv --python /usr/bin/python3.12 uvv. See uv vs pip for the differences.

Fix 3: install command-line tools with pipx or uv

If you want a tool such as Ruff or yt-dlp available everywhere, give it an isolated environment of its own:

pipx install ruff
# or
uv tool install ruff

Both create a virtual environment per tool, so the marker does not apply. pipx installed Ruff without complaint under a Python 3.12 that carries the marker. The error text above recommends pipx for exactly this case. See pipx vs uv tool.

Fix 4: the operating system package

Debian and Ubuntu package many Python libraries under names of the form python3-xyz, and the error message suggests apt install python3-xyz. Packages installed this way are tracked by the system. Versions are often older than the ones on PyPI, and not everything is packaged, but this is the right route for scripts that run as part of the system.

Last resort: —break-system-packages

pip install --break-system-packages requests

This overrides the check, and setting the environment variable PIP_BREAK_SYSTEM_PACKAGES=1 does the same. The PyPA specification says the option should not be on by default and should carry some connotation that its use is risky. On Ubuntu the installed package lands in /usr/local/lib/python3.12/dist-packages, separate from the distro’s own /usr/lib/python3/dist-packages, which is the split the specification recommends so that pip does not overwrite files owned by the system package manager. That reduces the damage but does not make it safe. It is acceptable in a throwaway Docker container, where nothing else depends on that Python, and a poor idea on a machine you use for other work.

In Docker

The official python Docker image builds Python from the python.org source tarball into /usr/local and its Dockerfile does not add the marker file, so pip install works there. If you start from a distribution base image such as ubuntu and install the distro’s Python, expect the marker: the specification recommends that distributors keep the file in container images. In that case create a virtual environment inside the image. See Docker for Python with uv.

Prevent it next time

Make python3 -m venv .venv the first command in every new project, and install packages with python -m pip so you always use the pip that belongs to the active interpreter. If a package still cannot be found after you install it, see ModuleNotFoundError: No module named. For a Windows setup, see how to install Python on Windows.

Frequently Asked Questions

What does error: externally-managed-environment mean?

The Python installation contains an EXTERNALLY-MANAGED marker file, placed there by whoever distributes it, which tells pip not to install or remove packages outside a virtual environment. This follows PEP 668 and stops pip from conflicting with packages managed by the operating system’s package manager.

How do I fix externally-managed-environment?

Create a virtual environment with python3 -m venv .venv, activate it and run pip install inside it. For command-line tools use pipx install or uv tool install, which create an isolated environment for you.

Is it safe to use —break-system-packages?

It overrides the check, and the PyPA specification says the option should carry a connotation that its use is risky. On Ubuntu, pip then installs into /usr/local rather than the directory the distro manages, but you can still end up with packages the system package manager does not know about. Use it in disposable environments such as a container and prefer a virtual environment otherwise.

Which systems show this error?

Any Python with an EXTERNALLY-MANAGED file in its standard library directory. Tested here: Ubuntu 24.04’s system Python and Python builds installed by uv. Homebrew’s python formulae also write the file. A Python compiled from upstream sources, such as the one in the official python Docker image, is not marked.

Can I delete the EXTERNALLY-MANAGED file?

You can, but it is not recommended. On Ubuntu the file belongs to the libpython3.12-stdlib package, so a reinstall or upgrade restores it, and deleting it removes the safeguard for the whole system Python. A virtual environment solves the problem without touching system files.