pypa/pip · error · InstallWheelBuildError
failed-wheel-build-for-install
failed-wheel-build-for-install
Error message
Failed to build installable wheels for some pyproject.toml based projects
What it means
Raised by `pip install` when one or more packages failed to build a wheel from source (pyproject.toml-based projects). InstallCommand.run at install.py:523 calls build() over reqs_to_build; if build_failures is non-empty it raises InstallWheelBuildError (a DiagnosticPipError with code 'failed-wheel-build-for-install'). The underlying causes are captured in build_failures and detailed in pip's preceding output.
Solutions
- Read the full build output above this error — it names the failing package and the real build error (e.g. missing compiler, missing header).
- Install build prerequisites: compiler toolchain, python-dev headers, and the package's documented system deps.
- Upgrade pip, setuptools, and wheel: `python -m pip install --upgrade pip setuptools wheel`.
- Do not disable build isolation (--no-build-isolation) unless build deps are preinstalled.
- Pin to a version of the package that ships a wheel for your platform, or use a binary distribution (e.g. manylinux wheel).
- For pure build-env issues, try `pip install <pkg> --only-binary :all:` to force wheel-only (fails fast if no wheel exists).
Example fix
// before pip install lxml # fails building from sdist, missing libxml2 // after # install system deps, then upgrade build tooling apt-get install libxml2-dev libxslt1-dev python3-dev python -m pip install --upgrade pip setuptools wheel pip install lxml
Defensive patterns
Strategy: try-catch
Validate before calling
# Prefer prebuilt wheels; detect absence before installing
import subprocess
def has_wheel(name, index_url=None):
cmd = ["pip", "index", "versions", name, "--json"]
if index_url:
cmd += ["--index-url", index_url]
r = subprocess.run(cmd, capture_output=True, text=True)
return r.returncode == 0
# Also ensure build toolchain is current
subprocess.run(["python", "-m", "pip", "install", "--upgrade", "pip", "setuptools", "wheel"], check=True)
Try / catch
# Capture build failure and fall back to a binary-only install
import subprocess
try:
subprocess.run(["pip", "install", name], check=True)
except subprocess.CalledProcessError:
# retry forcing wheels only
subprocess.run(["pip", "install", name, "--only-binary", ":all:"], check=True)
Prevention
- Keep pip, setuptools, wheel upgraded.
- Install system build deps (compiler, headers) before installing C-extension packages.
- Prefer --only-binary for packages you cannot build.
- Do not use --no-build-isolation unless build deps are preinstalled.
When it happens
Trigger: A requirement has no prebuilt wheel for the current platform/Python, so pip falls back to building from sdist; the build fails due to missing build dependencies, a broken pyproject.toml, missing system libraries, or incompatible compiler toolchain.
Common situations: Installing C-extension packages (e.g. numpy, lxml, psycopg2, cryptography) without wheels for the target Python/platform; missing build tools (gcc, python-dev headers, Rust for cryptography); PEP 517 build isolation disabled without the build deps installed; a broken package release on PyPI.
Related errors
- Can not combine '--user' and '--prefix' as they imply…
- Can not combine '--user' and '--target'
- Can not perform a '--user' install. User site-packages are…
- Target path exists but is not a directory, will not…
- --all-releases / --only-final option requires 1 argument.
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/c6ded47daaa60b55.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_internal/commands/install.py:531
else:
# If we're not replacing an already installed pip,
# we're not modifying it.
modifying_pip = pip_req.satisfied_by is None
protect_pip_from_modification_on_windows(modifying_pip=modifying_pip)
reqs_to_build = [
r for r in requirement_set.requirements_to_install if not r.is_wheel
]
_, build_failures = build(
reqs_to_build,
wheel_cache=wheel_cache,
verify=True,
allow_editables=True,
)
if build_failures:
raise InstallWheelBuildError(build_failures)
to_install = resolver.get_installation_order(requirement_set)
# Check for conflicts in the package set we're installing.
conflicts: ConflictDetails | None = None
should_warn_about_conflicts = (
not options.ignore_dependencies and options.warn_about_conflicts
)
if should_warn_about_conflicts:
conflicts = self._determine_conflicts(to_install)
# Don't warn about script install locations if
# --target or --prefix has been specified
warn_script_location = options.warn_script_location
if options.target_dir or options.prefix_path:
warn_script_location = False
# Warn on late imports so we don't silently pick up a moduleView on GitHub (pinned to f399c37189)