Python
Distutils
Error Handling
Installation
Debugging

DistutilsOptionError must supply either home or prefix/exec-prefix -- not both

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The error DistutilsOptionError: must supply either home or prefix/exec-prefix -- not both occurs when Python's distutils (or setuptools) receives conflicting installation path options. This typically happens on macOS with Homebrew Python, where the system sets --prefix via a config file while pip or the user passes --home. The fix is to create or edit ~/.pydistutils.cfg (or setup.cfg) to remove the conflicting option, or use virtual environments which avoid path conflicts entirely.

The Error

bash
1$ pip install some-package
2error: DistutilsOptionError: must supply either home or prefix/exec-prefix -- not both
3
4# Or during setup.py install
5$ python setup.py install --home=/usr/local
6error: DistutilsOptionError: must supply either home or prefix/exec-prefix -- not both

Why This Happens

Python's distutils supports two mutually exclusive installation schemes:

  • --home — installs to a single directory (e.g., --home=/usr/local)
  • --prefix — installs to a directory with Unix-style subdirectories (lib/, bin/, etc.)

When both are set — one by a config file and one by the command line — distutils refuses to proceed.

The most common scenario is on macOS with Homebrew Python:

bash
1# Homebrew creates this config file:
2cat /usr/local/Cellar/[email protected]/3.11.x/Frameworks/Python.framework/.../lib/python3.11/distutils/distutils.cfg
3# [install]
4# prefix=/usr/local/Cellar/[email protected]/3.11.x/Frameworks/...

When pip then tries to install with --home, the two options conflict.

Fix 1: Create ~/.pydistutils.cfg (macOS/Homebrew)

bash
1# Create or edit the user distutils config
2cat > ~/.pydistutils.cfg << 'EOF'
3[install]
4prefix=
5EOF

This empties the prefix setting, allowing --home to work. Alternatively:

bash
# Remove the file entirely if it exists
rm ~/.pydistutils.cfg

Virtual environments have their own isolated distutils config and avoid path conflicts:

bash
1# Create and activate a virtual environment
2python3 -m venv myenv
3source myenv/bin/activate
4
5# Install packages — no path conflicts
6pip install some-package
7
8# The virtual environment manages all paths internally

This is the cleanest fix because virtual environments do not inherit system-level distutils configuration.

Fix 3: Use --prefix Only

If you need to install to a specific location, use --prefix consistently:

bash
1# Install with prefix only
2pip install --prefix=/usr/local some-package
3
4# Or with setup.py
5python setup.py install --prefix=/usr/local

Do not mix --home and --prefix in the same installation.

Fix 4: Set PYTHONUSERBASE

For user-level installations without root:

bash
1# Install to user directory
2pip install --user some-package
3
4# Or set the user base directory
5export PYTHONUSERBASE=$HOME/.local
6pip install --user some-package
7
8# Verify installation location
9python -m site --user-site
10# /Users/username/.local/lib/python3.11/site-packages

The --user flag uses a separate installation scheme that does not conflict with --home or --prefix.

Fix 5: Environment Variable Override

bash
1# Temporarily unset conflicting options
2SETUPTOOLS_USE_DISTUTILS=stdlib pip install some-package
3
4# Or on macOS with Homebrew
5export PYTHONDONTWRITEBYTECODE=1
6pip install --no-binary :all: some-package

Diagnosing the Conflict

bash
1# Check where distutils looks for config
2python3 -c "
3import distutils.dist
4d = distutils.dist.Distribution()
5d.parse_config_files()
6print('Config files:', d.find_config_files())
7"
8
9# Check active install schemes
10python3 -c "
11import sysconfig
12print('Paths:')
13for name, path in sysconfig.get_paths().items():
14    print(f'  {name}: {path}')
15"
16
17# Check for user-level config
18cat ~/.pydistutils.cfg 2>/dev/null || echo "No user config"
19
20# Check for system-level config
21python3 -c "
22import os, sysconfig
23cfg = os.path.join(sysconfig.get_path('stdlib'), 'distutils', 'distutils.cfg')
24print(f'System config: {cfg}')
25if os.path.exists(cfg):
26    print(open(cfg).read())
27"

Python 3.12+: distutils Removed

Starting with Python 3.12, the distutils module was removed from the standard library. The setuptools package provides its own distutils:

bash
1# Python 3.12+ — install setuptools if needed
2pip install setuptools
3
4# The error may appear differently:
5# "setuptools.dist:DistutilsOptionError: must supply either home or prefix..."
6
7# Fix is the same: use virtual environments or remove conflicting config

Common Pitfalls

  • Editing the system distutils.cfg instead of user config: The system distutils.cfg (inside the Python installation directory) affects all users. Edit ~/.pydistutils.cfg for user-specific fixes, which takes precedence over the system config without affecting other users.
  • Using sudo pip install: Running sudo pip install on macOS with Homebrew Python changes the effective user and may bypass ~/.pydistutils.cfg. Avoid sudo pip entirely — use virtual environments or --user instead. Mixing sudo and non-sudo pip installs causes permissions chaos.
  • Forgetting to activate the virtual environment: Creating a venv with python3 -m venv myenv does not activate it. Running pip install without source myenv/bin/activate first still uses the system Python and hits the same config conflict.
  • Homebrew Python upgrade resetting config: Upgrading Python via brew upgrade python installs a new version with its own distutils.cfg. After upgrading, the conflict may reappear even if you fixed it before. Re-apply the fix or use virtual environments which survive upgrades.
  • Assuming the error is in your package: This error comes from Python's installation machinery, not from the package you are trying to install. The package's setup.py or pyproject.toml is not at fault. The fix is always in the Python/distutils configuration, not in the package itself.

Summary

  • The error occurs when --home and --prefix installation options conflict in distutils config
  • Most common on macOS with Homebrew Python, which sets prefix in distutils.cfg
  • Fix by creating ~/.pydistutils.cfg with prefix= (empty) or removing the file
  • Best fix: use virtual environments (python3 -m venv) which avoid all path conflicts
  • Use pip install --user for user-level installations without root
  • Python 3.12+ removed distutilssetuptools provides it, but the same fix applies

Course illustration
Course illustration

All Rights Reserved.