pypa/pip · error · UnsupportedWheel

Invalid Metadata-Version: {metadata_version_value}

Error message

Invalid Metadata-Version: {metadata_version_value}

What it means

Raised by `_verify_one` when the wheel's `Metadata-Version` field is present but is not itself a valid PEP 440 version (e.g. `2.1` parses fine, but `2.x` or `abc` does not). pip parses `Metadata-Version` with `Version(...)` and on `InvalidVersion` raises `UnsupportedWheel`. The value must be a parseable version because the spec version space is itself versioned.

Source

Thrown at src/pip/_internal/wheel_builder.py:114

        raise InvalidWheelFilename(
            f"Wheel has unexpected file name: expected {canonical_name!r}, "
            f"got {w.name!r}",
        )
    dist = get_wheel_distribution(FilesystemWheel(wheel_path), canonical_name)
    dist_verstr = str(dist.version)
    if canonicalize_version(dist_verstr) != canonicalize_version(w.version):
        raise InvalidWheelFilename(
            f"Wheel has unexpected file name: expected {dist_verstr!r}, "
            f"got {w.version!r}",
        )
    metadata_version_value = dist.metadata_version
    if metadata_version_value is None:
        raise UnsupportedWheel("Missing Metadata-Version")
    try:
        metadata_version = Version(metadata_version_value)
    except InvalidVersion:
        msg = f"Invalid Metadata-Version: {metadata_version_value}"
        raise UnsupportedWheel(msg)
    if metadata_version >= Version("1.2") and not isinstance(dist.version, Version):
        raise UnsupportedWheel(
            f"Metadata 1.2 mandates PEP 440 version, but {dist_verstr!r} is not"
        )


def _build_one(
    req: InstallRequirement,
    output_dir: str,
    verify: bool,
    editable: bool,
) -> str | None:
    """Build one wheel.

    :return: The filename of the built wheel, or None if the build failed.
    """
    artifact = "editable" if editable else "wheel"
    try:

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Inspect the wheel's `*.dist-info/METADATA` `Metadata-Version:` line and set it to a valid value such as `2.1` or `2.3`.
  2. Rebuild with a standard backend that emits a correct `Metadata-Version`.
  3. If the wheel was downloaded, re-download from the index to rule out corruption, and clear the pip cache (`pip cache purge`).

Example fix

# before
Metadata-Version: v2.1   # 'v2.1' is not a valid version literal here

# after
Metadata-Version: 2.1
Defensive patterns

Strategy: validation

Validate before calling

import zipfile
from packaging.version import Version, InvalidVersion

def validate_wheel_metadata_version(wheel_path: str) -> None:
    with zipfile.ZipFile(wheel_path) as z:
        meta = next(n for n in z.namelist() if n.endswith(".dist-info/METADATA"))
        text = z.read(meta).decode("utf-8")
    for line in text.splitlines():
        if line.startswith("Metadata-Version:"):
            val = line.split(":", 1)[1].strip()
            try:
                Version(val)
            except InvalidVersion:
                raise ValueError(f"Invalid Metadata-Version: {val!r}")
            return
    raise ValueError("Missing Metadata-Version")

Type guard

null

Try / catch

from pip._internal.exceptions import UnsupportedWheel
try:
    _verify_one(req, wheel_path)
except UnsupportedWheel as e:
    if str(e).startswith("Invalid Metadata-Version"):
        # rewrite METADATA with a valid value and rebuild
        ...

Prevention

When it happens

Trigger: `Version(metadata_version_value)` raises `InvalidVersion` for the value read from the wheel's `METADATA`. Triggered when a backend writes a malformed `Metadata-Version` value.

Common situations: Hand-edited METADATA files with typos; backends writing the wrong token (e.g. `Metadata-Version: v2.1` or `Metadata-Version: latest`); tools that substitute a placeholder; corrupted download producing junk in the field.

Related errors


AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04). Data as JSON: /data/errors/0234bb23767b8daf.json. Report an issue: GitHub.