If pip install stops with error: externally-managed-environment, your operating system is protecting its own Python. Since PEP 668, distros such as Debian 12+, Ubuntu 23.04+ and Kali, plus Homebrew’s Python on macOS, mark the system interpreter as managed by the OS package manager, and pip refuses to install into it. The fix is almost always the same: install into a virtual environment, or use a tool like pipx or uv that makes one for you.
What the error actually means
PEP 668 lets a Python distribution drop a file called EXTERNALLY-MANAGED into the standard library directory. When pip sees that marker and you are not inside a virtual environment, it refuses to install anything, because packages installed by pip could overwrite or conflict with the ones apt or brew manage. Plenty of system tools are written in Python, so a stray upgrade can quietly break them.
Two things catch people out:
pip install --useris blocked too. It used to be the standard workaround, but user-site installs still share the system interpreter, so PEP 668 covers them.- The error usually appears straight after an OS upgrade (Debian 11 to 12, an Ubuntu upgrade, or a fresh Homebrew Python), on commands that worked fine the week before.
The error message itself points you in the right direction. Here are the fixes, from most to least recommended.
Fix 1: create a virtual environment (best for projects)
For anything you are developing or running as a project, a virtual environment is the proper answer. It gives the project its own interpreter and its own site-packages, so pip can install whatever it likes without touching the system.
cd my-project
python3 -m venv .venv
source .venv/bin/activate
pip install requests
Once the environment is active, pip and python point at the copies inside .venv, and the error disappears. Run deactivate to leave it. On Debian and Ubuntu you may first need the venv module itself:
sudo apt install python3-venv
If you still see the error with the venv active, you are probably calling the system pip. Check with which python3 and which pip; both should point inside .venv/bin. I go through venvs in more depth in my beginner’s guide to Python virtual environments.
Fix 2: use pipx for command-line tools
If you just want a tool on your PATH (black, ruff, httpie, yt-dlp and so on) rather than a library to import, use pipx. It installs each application into its own isolated environment and links the command into ~/.local/bin.
# Debian / Ubuntu / Kali
sudo apt install pipx
pipx ensurepath
# macOS
brew install pipx
pipx ensurepath
Open a new terminal so the updated PATH takes effect, then install tools as normal:
pipx install black
pipx upgrade black
pipx uninstall black
Kali is a good example of this in practice: it ships pipx and recommends it for installing Python-based security tools that aren’t packaged in its repositories.
Fix 3: use uv instead of pip
uv is a fast, Rust-based replacement for pip, venv and pipx in one binary, and it sidesteps the problem by always working in virtual environments. For a project:
uv venv
source .venv/bin/activate
uv pip install requests
And for command-line tools, the pipx equivalent:
uv tool install ruff
If you haven’t tried it yet, my practical starter guide to uv covers installation and the project workflow.
Fix 4: install the distro package
Sometimes the library you need is already packaged by your distro. On Debian-based systems the naming convention is python3- followed by the package name:
apt search python3-requests
sudo apt install python3-requests
This is the right choice when a system script needs the library, because apt keeps it consistent with everything else on the machine. The trade-off is that you get the distro’s version, which may lag behind PyPI.
Fix 5: Homebrew on macOS
On a Mac, Homebrew’s Python is marked externally managed in the same way. Use a venv, pipx or uv for Python packages, and check whether the tool you want is available as a formula first, for example brew install yt-dlp. My beginner’s guide to Homebrew covers the basics.
What about –break-system-packages?
pip does have an override flag, --break-system-packages, which does exactly what its name says. It bypasses the protection, and it can break OS tools that depend on specific versions of system Python packages, sometimes in ways you won’t notice until a later upgrade fails. Treat it as a last resort for throwaway machines or containers, not a fix for your desktop or server. Every option above solves the problem without that risk.
Quick decision guide
- Working on a project or script: venv (or
uv venv). - Installing a command-line tool: pipx (or
uv tool install). - A system script needs a library: apt install python3-<name>.
- On a Mac: Homebrew formula if one exists, otherwise pipx, uv or a venv.
For a refresher on everyday pip commands once you are inside an environment, see my guide to using pip.

Leave a Reply
You must be logged in to post a comment.