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

  1. Create and activate a virtual environment: `python -m venv .venv && source .venv/bin/activate`, then install there.
  2. Use pipx (`pipx install <pkg>`) for installing CLI applications into isolated environments.
  3. Pass `--break-system-packages` to override the protection (not recommended, can break the OS Python).
  4. 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

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


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/26d980572f368b38. Report an issue: GitHub.