pypa/pip · error · InstallationError

is not a supported wheel on this platform.

Error message

{wheel.filename} is not a supported wheel on this platform.

What it means

In the legacy resolver, when a requirement link points to a wheel, pip builds a Wheel from the filename and checks wheel.supported(get_supported_tags()) (resolver.py:231-234). If the wheel's tags don't intersect the platform's supported tags, it raises InstallationError — the wheel was built for a different OS/arch/ABI/Python.

Solutions

  1. Let pip select the right wheel automatically (pip install <pkg> without an explicit .whl).
  2. Install from sdist so pip builds a compatible wheel locally.
  3. When targeting another platform, set --platform, --abi, and --python-version consistently.

Example fix

# before
pip install pkg-1.0-cp36-win_amd64.whl   # on Linux
# after
pip install pkg==1.0   # pip picks a Linux wheel or builds from sdist
Defensive patterns

Strategy: validation

Validate before calling

# Before installing a local wheel, verify its tags are supported here.
from pip._internal.utils.compatibility_tags import get_supported
from pip._internal.utils.wheel import Wheel
import sys
whl = sys.argv[1]
w = Wheel(whl)
if not w.supported(get_supported()):
    print(f"{whl} is NOT supported on this platform; pick another or build from sdist")
else:
    print("OK")

Prevention

When it happens

Trigger: Installing a wheel whose filename tags (platform/abi/python) don't match the current environment, e.g. cp36-win_amd64 on Linux, or cp311 on cp310.

Common situations: Downloading the wrong wheel from PyPI manually; --platform/--abi/--python-version flags mismatched; ABI-tag mismatch (cp3x vs abi3).

Related errors


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

Appendix: source

Thrown at src/pip/_internal/resolution/legacy/resolver.py:232

        """
        # If the markers do not match, ignore this requirement.
        if not install_req.match_markers(extras_requested):
            logger.info(
                "Ignoring %s: markers '%s' don't match your environment",
                install_req.name,
                install_req.markers,
            )
            return [], None

        # If the wheel is not supported, raise an error.
        # Should check this after filtering out based on environment markers to
        # allow specifying different wheels based on the environment/OS, in a
        # single requirements file.
        if install_req.link and install_req.link.is_wheel:
            wheel = Wheel(install_req.link.filename)
            tags = compatibility_tags.get_supported()
            if requirement_set.check_supported_wheels and not wheel.supported(tags):
                raise InstallationError(
                    f"{wheel.filename} is not a supported wheel on this platform."
                )

        # This next bit is really a sanity check.
        assert (
            not install_req.user_supplied or parent_req_name is None
        ), "a user supplied req shouldn't have a parent"

        # Unnamed requirements are scanned again and the requirement won't be
        # added as a dependency until after scanning.
        if not install_req.name:
            requirement_set.add_unnamed_requirement(install_req)
            return [install_req], None

        try:
            existing_req: InstallRequirement | None = requirement_set.get_requirement(
                install_req.name
            )

View on GitHub (pinned to f399c37189)