pypa/pip · error · UnsupportedWheel

is not a supported wheel for this platform. It can't be…

Error message

{wheel.filename} is not a supported wheel for this platform. It can't be sorted.

What it means

Raised by PackageFinder's candidate sorter (_sort_key) when a wheel filename's tags do not match any of the currently-supported platform/python/ABI tags. Wheel.find_most_preferred_tag() returns a ValueError when none of the wheel's compatibility tags intersect the environment's valid tags, which pip then wraps as UnsupportedWheel. The wheel cannot be ranked and is therefore unusable on this platform.

Solutions

  1. Switch to a Python version / platform for which a compatible wheel exists (check the package's 'Download files' on PyPI).
  2. Install from the source distribution instead (pip will build it if build deps are available), e.g. `pip install --no-binary :all: <pkg>`.
  3. Upgrade pip, which may recognize newer wheel tag formats and have broader compatibility.
  4. If a compatible wheel exists but pip isn't finding it, check --python-version, --platform, --only-binary, and --abi flags for cross-environment resolution.
  5. For maintainers, build and upload wheels for the target platform (manylinux, macosx, etc.).

Example fix

# before (only macOS x86_64 wheels, running on arm64)
pip install <pkg>
# after (force build from source)
pip install --no-binary <pkg> <pkg>
# or target a compatible python/platform
pip install --python-version 3.11 --only-binary :all: --platform macosx_11_0_arm64 <pkg>
Defensive patterns

Strategy: fallback

Validate before calling

from pip._vendor.packaging.tags import sys_tags
from pip._internal.utils.compatibility_tags import Wheel

def wheel_compatible(wheel_filename: str) -> bool:
    w = Wheel(wheel_filename)
    valid = {(t.interpreter, t.abi, t.platform) for t in sys_tags()}
    return any((w.pyver, w.abi, w.plat) in valid for _ in [0])

Try / catch

import subprocess
try:
    subprocess.run(['pip', 'install', '--only-binary', ':all:', pkg], check=True)
except subprocess.CalledProcessError:
    # no compatible wheel; fall back to building from source
    subprocess.run(['pip', 'install', '--no-binary', pkg, pkg], check=True)

Prevention

When it happens

Trigger: Resolving a requirement where the only available wheel was built for a different Python version (e.g. cp39 on a cp311 interpreter), a different OS (Windows wheel on Linux), a different architecture (x86_64 vs arm64), or an incompatible ABI. pip's candidate sorter hits this while ranking available files.

Common situations: Installing a package with no pure-python or source distribution and only platform-specific wheels for another OS/arch; running under a different Python minor version than the wheels available; constrained platforms like Apple Silicon or aarch64 where wheels are scarce; pinning to an old Python where newer wheels are incompatible.

Related errors


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

Appendix: source

Thrown at src/pip/_internal/index/package_finder.py:561

              comparison operators, but then different sdist links
              with the same version, would have to be considered equal
        """
        valid_tags = self._supported_tags
        support_num = len(valid_tags)
        build_tag: BuildTag = ()
        binary_preference = 0
        link = candidate.link
        if link.is_wheel:
            # can raise InvalidWheelFilename
            wheel = Wheel(link.filename)
            try:
                pri = -(
                    wheel.find_most_preferred_tag(
                        valid_tags, self._wheel_tag_preferences
                    )
                )
            except ValueError:
                raise UnsupportedWheel(
                    f"{wheel.filename} is not a supported wheel for this platform. It "
                    "can't be sorted."
                )
            if self._prefer_binary:
                binary_preference = 1
            build_tag = wheel.build_tag
        else:  # sdist
            pri = -(support_num)
        has_allowed_hash = int(link.is_hash_allowed(self._hashes))
        yank_value = -1 * int(link.is_yanked)  # -1 for yanked.
        return (
            has_allowed_hash,
            yank_value,
            binary_preference,
            candidate.version,
            pri,
            build_tag,
        )

View on GitHub (pinned to f399c37189)