Last updated: July 2026 — covers the “externally-managed-environment” error on Ubuntu 24.04
If you’ve recently seen this when running pip install:
error: externally-managed-environment
× This environment is externally managed
that’s Ubuntu (23.04+) enforcing PEP 668: the system Python belongs to apt, and pip is no longer allowed to modify it. The intended solution is exactly this article — a virtual environment.
1. Install the venv module
sudo apt update
sudo apt install python3-venv python3-pip
2. Create and activate an environment
cd ~/projects/myapp
python3 -m venv .venv # creates ./.venv with its own python + pip
source .venv/bin/activate
Your prompt gains a (.venv) prefix. From now on, python and pip refer to the environment — installs land in .venv/, never touching system Python, and the externally-managed error disappears:
pip install requests pandas
python myscript.py
Leave it with:
deactivate
3. Freeze and reproduce dependencies
pip freeze > requirements.txt # record exact versions
On another machine (or after deleting .venv):
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
This pair of commands is the whole reason venvs exist: every project gets its own dependency versions, and “works on my machine” becomes reproducible.
4. Day-to-day tips
- One venv per project, inside the project folder, named
.venv— editors like VS Code auto-detect it. - Add
.venv/to.gitignore; commitrequirements.txtinstead. - Run scripts without activating:
.venv/bin/python myscript.py— handy in cron jobs, which don’t source your shell profile. - Upgrade pip inside the venv freely:
pip install --upgrade pip. - Need a package available as a command system-wide (e.g.
httpie,ansible)? Usepipx(sudo apt install pipx), which auto-manages a venv per tool.
What about –break-system-packages?
pip install --break-system-packages bypasses the protection and installs into system Python. It exists for containers and throwaway boxes; on a machine you care about, it can genuinely break apt-managed tools that depend on specific Python library versions. On desktops and servers, the venv is the right answer — it’s three commands and it never conflicts.
