pypa/pip · error · FailedToPrepareCandidate

Failed to build ' ' when

Error message

Failed to build '{package_name}' when {failed_step.lower()}

What it means

_prepare (candidates.py:252-265) catches InstallationSubprocessError from the PEP 517 build backend (metadata generation or wheel building) and re-raises it as FailedToPrepareCandidate, surfacing the package name, the requirement chain, and the failed step (e.g. 'building wheel'). The actual build log appears above this summary error.

Solutions

  1. Read the build backend output printed above the FailedToPrepareCandidate line for the root cause.
  2. Install build prerequisites (build-essential, python3-dev, wheel, setuptools).
  3. Debug with pip install --no-build-isolation to use the current env's build deps.
  4. Pin to a version that ships prebuilt wheels to avoid building from sdist.

Example fix

# before
pip install pkg   # builds from sdist, fails
# after
pip install pkg==1.2 --only-binary :all:   # use prebuilt wheel
Defensive patterns

Strategy: try-catch

Validate before calling

# Prefer prebuilt wheels; check availability before building from sdist.
import subprocess, sys
pkg = "pkg"
r = subprocess.run([sys.executable, "-m", "pip", "index", "versions", pkg], capture_output=True, text=True)
print(r.stdout)  # inspect available versions; prefer --only-binary

Try / catch

# When automating installs, catch the failure and fall back to a wheel-only install.
import subprocess, sys
def safe_install(pkg):
    try:
        subprocess.check_call([sys.executable, "-m", "pip", "install", pkg])
    except subprocess.CalledProcessError:
        subprocess.check_call([sys.executable, "-m", "pip", "install", "--only-binary", ":all:", pkg])
safe_install("pkg")

Prevention

When it happens

Trigger: The build backend subprocess exits non-zero while preparing metadata or building a wheel for a sdist requirement (missing compiler, broken setup.py, build-dep resolution failure).

Common situations: Missing system build tools (gcc, python-dev headers); broken pyproject.toml build backend; network failure fetching build-system.requires in isolation; syntax error in setup.py.

Related errors


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

Appendix: source

Thrown at src/pip/_internal/resolution/resolvelib/candidates.py:261

    def _prepare(self) -> BaseDistribution:
        try:
            dist = self._prepare_distribution()
        except HashError as e:
            # Provide HashError the underlying ireq that caused it. This
            # provides context for the resulting error message to show the
            # offending line to the user.
            e.req = self._ireq
            raise
        except InstallationSubprocessError as exc:
            if isinstance(self._ireq.comes_from, InstallRequirement):
                request_chain = self._ireq.comes_from.from_path()
            else:
                request_chain = self._ireq.comes_from

            if request_chain is None:
                request_chain = "directly requested"

            raise FailedToPrepareCandidate(
                package_name=self._ireq.name or str(self._link),
                requirement_chain=request_chain,
                failed_step=exc.command_description,
            )

        self._check_metadata_consistency(dist)
        return dist

    def iter_dependencies(self, with_requires: bool) -> Iterable[Requirement | None]:
        # Emit the Requires-Python requirement first to fail fast on
        # unsupported candidates and avoid pointless downloads/preparation.
        yield self._factory.make_requires_python_requirement(self.dist.requires_python)
        requires = self.dist.iter_dependencies() if with_requires else ()
        for r in requires:
            yield from self._factory.make_requirements_from_spec(str(r), self._ireq)

    def get_install_requirement(self) -> InstallRequirement | None:
        return self._ireq

View on GitHub (pinned to f399c37189)