What This Error Means
pip delegated part of the install to an external build step (PEP 517 backend or legacy setup.py) and that subprocess failed.
How to Fix It
- Upgrade build tooling in the environment:
python -m pip install -U pip setuptools wheel. - Install the OS-level build dependencies required by the package (compiler + development headers).
- If possible, use a Python version and platform combination that has prebuilt wheels for the package.
- Retry with
--no-cache-dir -vto rule out corrupted cached downloads. - If the log shows a missing system library, install that library and retry.
Why It Happens
- A required system dependency or header is missing (common: Python headers, OpenSSL headers, libffi, etc.).
- A compiler/toolchain is missing (gcc/clang on Linux/macOS, MSVC Build Tools on Windows, Rust for some packages).
- The package doesn't support your Python version yet (so only source builds exist and they fail).
- The build backend (pyproject.toml build system) has a bug or missing build requirements.
How to Verify
- Re-run
python -m pip install <package>and confirm the build step completes without error. - Run
python -c 'import <module>'(or run the package's self-test) to confirm installation is functional.
Manual build failure triage
- Re-run with verbosity:
python -m pip install -v <package>and scroll to the first compilation/build error above the summary. - Check whether a wheel should exist for your environment (Python version, OS, architecture).
- Confirm build tools are present (compiler, headers, language toolchains like Rust if required).
Common CLI Output
error: subprocess-exited-with-errornote: This error originates from a subprocess, and is likely not a problem with pip.error: metadata-generation-failed Why pip runs subprocesses during installs
- If a package doesn't have a compatible prebuilt wheel for your platform/Python, pip falls back to building from source.
- For modern packages, this uses a PEP 517 build backend (run in a subprocess). For older packages, it may run
setup.py. - pip reports a high-level error, but the real cause is usually earlier in the log (compiler errors, missing headers, missing build dependencies, or incompatible Python).
Prevention Tips
- Prefer wheels in CI by using supported Python versions and platforms.
- Document required OS dependencies for your project and install them in dev/CI images.
- Use an internal wheelhouse or cache to reduce variability in builds.
Where This Can Be Triggered
github.com/pypa/pip/blob/25.3/src/pip/_internal/exceptions.py
pip defines the diagnostic error subprocess-exited-with-error (and the related metadata-generation-failed) in its exception classes, the underlying cause is usually earlier in the build output. - GitHub
class InstallationSubprocessError(DiagnosticPipError, InstallationError):
"""A subprocess call failed."""
reference = "subprocess-exited-with-error"
def __init__(
self,
*,
command_description: str,
exit_code: int,
output_lines: list[str] | None,
) -> None:
if output_lines is None:
output_prompt = Text("No available output.")
else:
output_prompt = (
Text.from_markup(f"[red][{len(output_lines)} lines of output][/]\n")
+ Text("".join(output_lines))
+ Text.from_markup(R"[red]\\[end of output][/]")
)
super().__init__(
message=(
f"[green]{escape(command_description)}[/] did not run successfully.\n"
f"exit code: {exit_code}"
),
context=output_prompt,
hint_stmt=None,
note_stmt=(
"This error originates from a subprocess, and is likely not a "
"problem with pip."
),
)
self.command_description = command_description
self.exit_code = exit_code
def __str__(self) -> str:
return f"{self.command_description} exited with {self.exit_code}"
class MetadataGenerationFailed(DiagnosticPipError, InstallationError):
reference = "metadata-generation-failed"
def __init__(
self,
*,
package_details: str,
) -> None:
super().__init__(
message="Encountered error while generating package metadata.",
context=escape(package_details),
hint_stmt="See above for details.",
note_stmt="This is an issue with the package mentioned above, not pip.",
)