PythonMastery
reference 4 min read · lesson 42 of 45 in Errors

error: externally-managed-environment

1 · The lesson

read

What this error means

pip refused to install into the Python that came with your operating system. That Python belongs to the OS package manager — apt on Debian and Ubuntu, Homebrew on a Mac — and the OS itself runs tools written against the exact package versions it shipped. Since pip 23.0, pip honours a marker file, EXTERNALLY-MANAGED, that those distributions drop next to the standard library, and stops rather than overwrite packages the system depends on. The rule is PEP 668.

When you see it

text
$ 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.

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.

Why it happens

Nothing broke. Your machine got newer. Debian 12, Ubuntu 23.04 and later, Raspberry Pi OS Bookworm and Homebrew's Python all mark their Python as externally managed, so a command that worked on your old laptop — or in a tutorial written in 2021 — now stops. pip install --user is refused too: packages in your home directory still shadow the ones the OS relies on.

How to fix it

Option 1 — make a virtual environment. This is the right answer nine times out of ten. Your project gets its own Python and its own packages, and the system copy is never touched.

bash
python3 -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
python -m pip install requests

On Debian and Ubuntu, if the first line fails with ensurepip is not available, install the missing piece once: sudo apt install python3-venv.

Option 2 — a command-line tool you want everywhere? Use pipx. black, httpie, yt-dlp and friends are applications, not libraries. pipx gives each one its own hidden virtual environment and puts the command on your PATH.

bash
sudo apt install pipx            # macOS: brew install pipx
pipx ensurepath
pipx install black

Option 3 — the distribution already packages it. For common libraries used by system scripts, the OS package is fine: sudo apt install python3-requests. You get the version Debian tested, which is often a year or two old.

Don't reach for --break-system-packages. It does exactly what it says. The day pip upgrades a library that apt or your desktop tools import, those tools fail — and the error shows up in something that has nothing to do with Python, weeks later. The one defensible use is a throwaway container, where there is no system to break.

When you'd actually see this in real code

  • A setup guide says pip install -r requirements.txt and you run it on a fresh Ubuntu 24.04 machine.
  • A Dockerfile based on debian:bookworm runs pip install straight into the system Python. Use the official python:3.13-slim image instead: its Python is not marked.
  • You upgraded macOS or Homebrew, and a pip install that worked last month now refuses.
  • A Raspberry Pi tutorial written before 2023 tells you to sudo pip install a sensor library.

See Also