Fix 'error: externally-managed-environment' When Installing Python Packages with pip

beginner🐍 Python2026-05-21| Ubuntu 23.04+, Debian 12+, Fedora 38+, Linux Mint 21.2+ with Python 3.11+

Error Message

error: externally-managed-environment
#python#pip#linux#virtualenv

The Error

You run a simple pip install command and get hit with this:

$ pip install requests
error: externally-managed-environment

Γ— This environment is managed by an external package manager.
╰─> To install Python packages system-wide, use 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 the python3-full apt package 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 the pipx package
    installed.

    If you are using a Python Virtual Environment (like .venv), make
    sure it is active before running pip install. Consult the
    python3 venv documentation for instructions.

    For more information, visit https://packaging.python.org/en/latest/specifications/externally-managed-environments/

Root Cause

Starting with Python 3.11 and PEP 668, distros like Ubuntu 23.04+, Debian 12 (Bookworm), and Fedora 38+ mark their system Python as "externally managed". The distro's package manager β€” apt, dnf, whatever β€” owns that Python installation. pip is blocked from touching it.

Before this change, pip install would silently drop packages into the system Python's site-packages. That caused real headaches: pip-installed packages would clash with distro-packaged ones, taking down system tools that depended on specific versions. Package managers updating python3-requests from 2.28 to 2.31, for instance, could silently break a pip-installed package pinned to an older API.

The block is enforced by a single marker file:

/usr/lib/python3.x/EXTERNALLY-MANAGED

pip sees that file and refuses to proceed. Simple as that.

Fix: Use a Virtual Environment (The Right Way)

Nine times out of ten, this is the move. A virtual environment gives your project its own isolated Python and package directory β€” completely separate from the system Python.

Step 1: Create a virtual environment

# In your project directory
python3 -m venv .venv

Step 2: Activate it

# On Linux/macOS
source .venv/bin/activate

# On Windows (if you're not on WSL)
.venv\Scripts\activate

Step 3: Install your packages normally

pip install requests

Verify it worked

# Check where pip is resolving to
which pip
# Should show: /your/project/.venv/bin/pip

# Confirm the package installed
pip show requests

When you're done, deactivate with:

deactivate

Fix: For CLI Tools β€” Use pipx

Installing a standalone command-line tool? Don't use a project venv for that. pipx is built exactly for this case. It spins up an isolated environment per tool, then wires the binary into your PATH β€” you never think about it again.

# Install pipx
sudo apt install pipx
pipx ensurepath

# Then install any CLI tool
pipx install black
pipx install httpie

After that, black and http work from anywhere. No venv to activate, no environment to babysit.

Fix: Override the Block (Quick but Risky)

You can force pip past the block with the --break-system-packages flag:

pip install requests --break-system-packages

The flag name is intentionally scary. It exists so you can't blame anyone but yourself.

There are legitimate uses β€” inside a Docker container, for example, where the system is already isolated and you don't care about package conflicts. But on your actual dev machine? Don't. A pip-installed package that collides with a system one can take out apt, network managers, or anything else that leans on the system Python.

Fix: Delete the Marker File (Not Recommended)

Some guides tell you to just remove the file that triggers the error:

# Find the file
python3 -c "import sys; print(sys.prefix)"

# Example path on Ubuntu 23.10
sudo rm /usr/lib/python3.11/EXTERNALLY-MANAGED

Sure, it works. It's also roughly equivalent to pulling the battery out of your smoke detector. The protection is gone permanently, and future pip installs will quietly stomp on system packages. Spinning up a venv takes 10 seconds β€” do that instead.

Fix: Install via apt for System-Wide Packages

Some packages genuinely need to be available across your whole system, not just one project. Check if your distro already ships them:

# Search available packages
apt search python3-requests

# Install via apt
sudo apt install python3-requests

Packages installed through apt slot cleanly into the system and never trigger this error. The catch: distro packages lag behind PyPI, sometimes by months.

Common Scenario: Setting Up a New Project from Scratch

Here's the full workflow, start to finish:

# 1. Make sure python3-venv is installed (Ubuntu)
sudo apt install python3-venv python3-full

# 2. Create your project
mkdir myproject && cd myproject

# 3. Create a virtual environment
python3 -m venv .venv

# 4. Activate
source .venv/bin/activate

# 5. Install packages freely
pip install flask sqlalchemy gunicorn

# 6. Save dependencies
pip freeze > requirements.txt

Common Scenario: Docker Containers

Debian and Ubuntu base images trigger this error in Dockerfiles too. Since containers are already isolated, --break-system-packages is the pragmatic call here:

FROM python:3.12-slim

COPY requirements.txt .
RUN pip install --break-system-packages -r requirements.txt

Two other options: switch to the official python:3.12 image (no restriction), or create a proper venv inside the container if you want belt-and-suspenders isolation.

Prevention

  • Create a .venv at the start of every Python project β€” treat it like creating the repo itself, not something you do when things break.
  • Add .venv/ to your .gitignore immediately.
  • Reach for pipx whenever you're installing a CLI tool, not a library.
  • Working on a team? Put the venv setup in your README. Future teammates will thank you.
  • Take a look at uv β€” a Rust-based replacement for pip and venv that's 10–100x faster and handles environment creation automatically: uv venv && uv pip install requests.

Related Error Notes