pypa/pip · error · ExternallyManagedEnvironment
This environment is externally managed
Error message
This environment is externally managed
What it means
Raised as ExternallyManagedEnvironment by check_externally_managed (misc.py:646) when pip detects an EXTERNALLY-MANAGED marker file in the Python installation's stdlib directory and is not running inside a virtualenv. This implements PEP 668: system package managers (Debian, Fedora, Homebrew, etc.) place the marker to prevent pip from breaking the OS-managed Python environment. The exception provides diagnostic hints (use a venv, --break-system-packages, or pipx).
Source
Thrown at src/pip/_internal/utils/misc.py:646
"To modify pip, please run the following command:\n{}".format(
" ".join(new_command)
)
)
def check_externally_managed() -> None:
"""Check whether the current environment is externally managed.
If the ``EXTERNALLY-MANAGED`` config file is found, the current environment
is considered externally managed, and an ExternallyManagedEnvironment is
raised.
"""
if running_under_virtualenv():
return
marker = os.path.join(sysconfig.get_path("stdlib"), "EXTERNALLY-MANAGED")
if not os.path.isfile(marker):
return
raise ExternallyManagedEnvironment.from_config(marker)
def is_console_interactive() -> bool:
"""Is this console interactive?"""
return sys.stdin is not None and sys.stdin.isatty()
def hash_file(path: str, blocksize: int = 1 << 20) -> tuple[Any, int]:
"""Return (hash, length) for path using hashlib.sha256()"""
h = hashlib.sha256()
length = 0
with open(path, "rb") as f:
for block in read_chunks(f, size=blocksize):
length += len(block)
h.update(block)
return h, length
View on GitHub (pinned to f399c37189)
Solutions
- Create and activate a virtual environment: `python -m venv .venv && source .venv/bin/activate`, then install there.
- Use pipx (`pipx install <pkg>`) for installing CLI applications into isolated environments.
- Pass `--break-system-packages` to override the protection (not recommended, can break the OS Python).
- Use `--target` to install into a user-specified directory without touching the system environment.
Example fix
// before $ pip install requests error: externally-managed-environment // after $ python -m venv .venv $ source .venv/bin/activate $ pip install requests
Defensive patterns
Strategy: validation
Validate before calling
import os, sys, sysconfig, venv
def ensure_venv_or_warn():
"""Check if running in a venv or warn about externally-managed envs."""
in_venv = sys.prefix != sys.base_prefix
marker = os.path.join(sysconfig.get_path('stdlib'), 'EXTERNALLY-MANAGED')
if not in_venv and os.path.isfile(marker):
print('System Python is externally managed. Create a venv first:')
print(f' {sys.executable} -m venv .venv && source .venv/bin/activate') Type guard
import sys, sysconfig, os
def is_externally_managed() -> bool:
"""True if the current Python is externally managed (PEP 668)."""
in_venv = sys.prefix != sys.base_prefix
if in_venv:
return False
marker = os.path.join(sysconfig.get_path('stdlib'), 'EXTERNALLY-MANAGED')
return os.path.isfile(marker) Try / catch
from pip._internal.exceptions import ExternallyManagedEnvironment
try:
# pip install operation
pass
except ExternallyManagedEnvironment:
# Fallback: create venv or use --break-system-packages
pass Prevention
- Always create and activate a venv before installing packages on system Python 3.11+.
- Use pipx for standalone CLI tools to get isolated environments automatically.
- In Dockerfiles, create a venv or use --break-system-packages deliberately.
When it happens
Trigger: check_externally_managed() is called at the start of an install operation. It returns early if running_under_virtualenv() (line 641), checks for os.path.join(sysconfig.get_path('stdlib'), 'EXTERNALLY-MANAGED') (line 643), and if that file exists, raises at line 646.
Common situations: Running `pip install` directly on system Python 3.11+ on Debian/Ubuntu, Fedora, Arch, Homebrew, or similar PEP 668-compliant distributions. Fresh OS installs where users haven't created a venv yet. CI images based on system Python.
Related errors
- Can not open an editor for a file name containing " {fname}
- Can not perform a '--user' install. User site-packages are n
- Unexpected file name derived from URL: {name!r}
- Invalid script entry point name {entry.name!r}: the script w
- The wheel {!r} has a file {!r} trying to install outside the
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/26d980572f368b38.
Report an issue: GitHub.