The error, verbatim
Jump to the fix ↓error: externally-managed-environment
× This environment is externally managed
Tested on
- OS
- Ubuntu 22.04, 24.04, 26.04; Debian 12, 13; Fedora 44; python:3.13-slim (containers); macOS 26.6
- Python / pip
- 3.10 to 3.15 / pip 22.0 to 26.2
- uv
- 0.13.6
- Where
- GitHub Actions ubuntu-24.04 and macos-latest
✓ Last re-run on GitHub Actions · see the run · all repros
Contents
Whether you see this depends entirely on where your Python came from. In clean containers, plain pip install was refused on Ubuntu 24.04 and 26.04, Debian 12 and 13 and Homebrew’s Python on macOS, and allowed on Ubuntu 22.04, Fedora 44 and the official python:3.13-slim image. The refusing systems mark their own Python as “externally managed” (PEP 668): the package manager owns it, so pip won’t change it. In a clean Ubuntu 24.04 container, with Python 3.12.3 and pip 24.0, pip3 install requests stopped with:
error: externally-managed-environment
× This environment is externally managed
The usual workarounds don’t get past it. Both of these failed the same way:
| Tried | Result |
|---|---|
pip3 install --user requests |
error: externally-managed-environment |
python3 -m pip install requests as root |
error: externally-managed-environment |
Which systems do this
I ran the same python3 -m pip install six on each system’s own Python:
| System | Python, pip | pip install |
|---|---|---|
| Ubuntu 22.04.5 | 3.10.12, 22.0.2 | ✅ installs |
| Ubuntu 24.04.5 | 3.12.3, 24.0 | ❌ externally-managed-environment |
| Ubuntu 26.04.1 | 3.14.4, 25.1.1 | ❌ externally-managed-environment |
| Debian 12 (bookworm) | 3.11.2, 23.0.1 | ❌ externally-managed-environment |
| Debian 13 (trixie) | 3.13.5, 25.1.1 | ❌ externally-managed-environment |
| Fedora 44 | 3.14.8, 26.0.1 | ✅ installs |
Docker python:3.13-slim |
3.13.18, 26.2.2 | ✅ installs |
| macOS 26.6, Homebrew Python | 3.15.1, 26.2.2 | ❌ externally-managed-environment |
The error comes from a file the distribution ships, /usr/lib/python3.X/EXTERNALLY-MANAGED. It existed on every Linux system that refused and on none that installed. That’s why Ubuntu 22.04 installs and 24.04 refuses, and why the official python Docker images don’t show it: their Python lives in /usr/local, not the distribution’s.
On macOS the message talks about Homebrew instead (“If you wish to install a Python library that isn’t in Homebrew, use a virtual environment”), and --user failed there too.
Which fix is right depends on what you’re installing.
For a project: a virtual environment
Create a virtual environment for the project and install into it:
python3 -m venv .venv
.venv/bin/pip install requests
.venv/bin/python your_script.py(Or source .venv/bin/activate once, then plain pip and python.)
On Debian and Ubuntu, python3 -m venv fails first if the venv module isn’t installed. That’s the next error most people hit:
The virtual environment was not created successfully because ensurepip is not
available. On Debian/Ubuntu systems, you need to install the python3-venv
package using the following command.
apt install python3.12-venv
The version in the package name matches your Python (3.10 on Ubuntu 22.04, 3.11 on Debian 12, 3.13 on Debian 13, 3.14 on Ubuntu 26.04), so copy it from your own message. In the September test on Ubuntu 24.04, apt install python3-venv was enough too.
Or let uv make the venv
uv brings its own venv support, so it works even without python3-venv:
uv venv
uv pip install requests
.venv/bin/python your_script.pyuv doesn’t get you around the rule, though. uv pip install --system attrs refused on the same systems:
error: The interpreter at `/usr` is externally managed, and indicates the following:
For a command-line tool: pipx
For tools you run as commands (httpie, black, poetry…), pipx gives each one its own environment and puts the command on your PATH:
sudo apt install pipx
pipx install httpieFor a library the system already packages: apt
Many common libraries exist as distribution packages named python3-<name>:
sudo apt install python3-requestsThe same switch hides in two other places, so check for them if pip installs system-wide on one machine and not another. Both let pip install through on Ubuntu 24.04 and 26.04 and Debian 12 and 13:
- the environment variable
PIP_BREAK_SYSTEM_PACKAGES=1 - a pip config entry, set with
pip config set global.break-system-packages true
In a Dockerfile
If your image starts FROM ubuntu:24.04 or FROM debian:12 and runs pip install, the build fails with this error. The simplest fix is the official Python image, whose Python isn’t marked as externally managed:
FROM python:3.13-slim
RUN pip install requests
If you need the Ubuntu or Debian base, use the venv fix above inside the image rather than adding --break-system-packages.
How this was tested
A clean ubuntu:24.04 container on GitHub Actions’ ubuntu-24.04 runner, October 17, 2026, with python3-pip, python3-venv and pipx from apt (Python 3.12.3, pip 24.0). Each case ran in the same container in the order shown. The runner’s own Python was not used, because GitHub’s image is set up to allow pip installs. The script and workflow are public. Every message above is the real output.
November 1, 2026: the same check in clean ubuntu:22.04, ubuntu:24.04, ubuntu:26.04, debian:12, debian:13, fedora:latest (Fedora 44) and python:3.13-slim containers, each with only python3-pip added, plus python3 -m venv without python3-venv, PIP_BREAK_SYSTEM_PACKAGES, the pip config setting and uv 0.13.6; and Homebrew’s Python 3.15.1 on a GitHub macos-latest runner (macOS 26.6.2). Scripts: pep668/distros.sh and pep668/macos.sh in the same repo.
— N.K., end of entry No.074