Python

Written & tested for accuracy by a developer (not AI)

Fix: error: externally-managed-environment on Mac

The 'error: externally-managed-environment' message means pip refused to install into your system Python. Fix it with uv, pipx, or a virtual environment. Four fixes ranked, and when to use each.

This error means pip refused to install into a Python that another tool manages. Nothing is broken and you have not done anything wrong. Python is deliberately protecting an installation that Homebrew or uv manages. To fix it, install the package somewhere else: use uv, use pipx for command-line tools, or create a virtual environment. All three are below, in order of preference, along with a last-resort override and when it is safe to use.

$ pip install <package>
error: externally-managed-environment

Fixing this error is one step in setting up your Mac for Python development. See the Mac development setup guide.

Before you get started

You'll need a terminal application to fix the error and run Python. Apple includes the Mac terminal but I prefer Warp Terminal. Warp is an easy-to-use terminal application, with AI assistance to help you learn and remember terminal commands. Download Warp Terminal now; it's FREE and worth a try.

Fix the error: externally-managed-environment

You have four ways to fix this, in order of preference:

  1. Use uv (recommended): See Install uv on Mac. Use uv, the modern Python package and project manager. Its own commands install packages into a project environment, so the error never comes up. Best choice for almost everyone.
  2. Use pipx for CLI tools: See Install pipx on Mac. If you're installing a standalone Python tool (such as Black, Ruff, youtube-dl, httpie, or cookiecutter), pipx is purpose-built for this and avoids the error.
  3. Use a virtual environment: create a venv with the standard library venv module, then run pip install inside it. Inline instructions below. (See Python's official venv documentation for full reference.)
  4. Override the lockout with --break-system-packages: Only as a last resort. Explanation and warning below.

Why this happens

Python 3.12+ implements PEP 668, which lets a Python distribution mark its install as "externally managed" so pip install can't write packages into the system site-packages directory. The mark is a file named EXTERNALLY-MANAGED that the distributor places next to the standard library, and each distributor decides whether to add it.

On Mac, two Pythons carry the mark: Homebrew's Python (the most common installed Python) and any Python that uv installed for you. Both refuse a bare pip install.

Apple's bundled system Python is the exception, and it is worth knowing because so many guides say otherwise. The Python 3.9 that arrives with the Xcode Command Line Tools carries no EXTERNALLY-MANAGED file, so pip install does not refuse. It falls back to a per-user install instead, showing "Defaulting to user installation because normal site-packages is not writeable" and writing the package into ~/Library/Python/3.9/lib/python/site-packages. That directory is not on your PATH by default, so a command-line tool installed this way still will not run. See Check If Python Is Installed for why you should keep project work off Apple's Python anyway.

The error is by design. It protects a managed Python from package conflicts and partially-broken upgrades. The fix is not to bypass the protection. The fix is to install your packages somewhere else (uv, pipx, or a virtual environment).

Choose the right fix

Match your situation to one of the four options:

  • If you are starting a new Python project: use uv. My recommended solution as it replaces pip, venv, and pyenv in one tool.
  • If you are installing a standalone Python CLI tool (such as Black, Ruff, httpie, cookiecutter, or youtube-dl): use pipx.
  • If you are already comfortable with pip and you just need packages for one project: use a virtual environment (python -m venv).
  • If you are installing on a one-off ephemeral system (such as a CI image or throwaway VM) and you understand the risk: use --break-system-packages.

Fix 1: use uv (recommended)

The tool uv is an all-in-one Python package and project manager from Astral, written in Rust. It manages Python versions, virtual environments, and packages in a single tool. Its commands install packages into a project's own virtual environment rather than into a system site-packages directory, so PEP 668 never blocks them.

Install uv with Homebrew (or with the official installer curl -LsSf https://astral.sh/uv/install.sh | sh):

$ brew install uv

Then add packages to a uv-managed project, or use the pip-compatible interface:

$ uv add <package>
$ uv pip install <package>

See the full guide: Install uv on Mac.

Expect the same error from a uv-managed Python

Installing uv does not make a bare pip install start working. A Python you installed with uv python install is itself marked externally managed, so pointing pip at it fails with the same PEP 668 error and a uv-specific explanation:

$ pip install <package>
error: externally-managed-environment
This Python installation is managed by uv and should not be modified.

The trap catches anyone who runs uv python install --default to get a python command and then falls back on old habits. Reach for uv's own commands instead: use uv add <package> inside a project, uv pip install <package> inside an environment uv created, and uv run to run your code with the project's dependencies. For a standalone command-line application, use uv tool install <package>.

Fix 2: use pipx for CLI tools

The tool pipx installs each Python command-line tool in its own isolated environment, so dependencies never conflict and PEP 668 is not triggered. It is the right tool for standalone applications such as youtube-dl, httpie, cookiecutter, Black, and Ruff.

Install pipx with Homebrew:

$ brew install pipx
$ pipx ensurepath

Then install a tool:

$ pipx install <package>

See the full guide: Install pipx on Mac.

Fix 3: use a virtual environment (venv)

A virtual environment is a self-contained directory with its own Python and its own site-packages. Running pip install inside an activated venv writes to the venv, not to the system Python, so PEP 668 does not apply.

Create, activate, install, and deactivate:

$ python -m venv .venv
$ source .venv/bin/activate
$ pip install <package>
$ deactivate   # when done

Use python -m pip install <package> instead of pip install <package> to avoid a "shadowed" pip. The python -m prefix ensures the package goes into the Python interpreter you actually have activated.

For full reference, see Python's official venv documentation.

Fix 4: override the lockout with --break-system-packages

Warning: Bypassing PEP 668 can break your system Python or Homebrew's Python, and can silently introduce dependency conflicts that surface much later. Don't do this on a Mac you rely on for development. Use this only on ephemeral systems (such as CI runners, disposable Docker images, or scratch VMs) where breaking the Python install has no downstream cost.

Pass the flag on a single command:

$ pip install --break-system-packages <package>

Or set the environment variable so every pip install in the session uses it:

$ export PIP_BREAK_SYSTEM_PACKAGES=1

If you're tempted to use this on your main Mac, use uv or pipx instead.

Other common errors

For the error:

$ python ...
zsh: command not found: python

See our guide command not found: python.

For the error:

$ pip install <package>
zsh: command not found: pip

See our guide command not found: pip.

You'll see these errors if Python or Pip is not installed or not in the Mac PATH.

Continue setting up your Mac

Don't miss the full visual roadmap and checklist that shows how to set up a Mac for software development, with all the essential tools and settings you might not yet know about.