pypa/pip · error · UnsupportedWheel
Metadata 1.2 mandates PEP 440 version, but {dist_verstr!r} i
Error message
Metadata 1.2 mandates PEP 440 version, but {dist_verstr!r} is not What it means
Raised by `_verify_one` when the wheel declares `Metadata-Version >= 1.2` (which mandates a PEP 440 compliant version string) but the distribution's version object is not a `pip._vendor.packaging.version.Version` (i.e. it is an `EpochVersion`/Legacy/invalid form). PEP 345/426/PEP 440 require versions in metadata >= 1.2 to be strict PEP 440; otherwise the wheel is considered unsupported.
Source
Thrown at src/pip/_internal/wheel_builder.py:116
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:
ensure_dir(output_dir)
except OSError as e:View on GitHub (pinned to d7d0d0a394)
Solutions
- Rewrite the version string to be PEP 440 compliant: `1.0a1`, `1.0rc1`, `1.0.post1`, `1.0.dev1` (use dots not dashes, no leading `v`).
- If you must keep a non-PEP 440 version, you cannot declare `Metadata-Version >= 1.2`; but the right fix is to make the version compliant.
- Use `from packaging.version import Version; Version(your_version)` locally to validate before building.
Example fix
# before [project] name = "mypkg" version = "1.0-rc1" # not PEP 440 # METADATA: Metadata-Version: 2.1 # after [project] name = "mypkg" version = "1.0rc1" # PEP 440 compliant
Defensive patterns
Strategy: validation
Validate before calling
from packaging.version import Version, InvalidVersion
def assert_pep440_version(version: str) -> None:
try:
Version(version)
except InvalidVersion:
raise ValueError(f"{version!r} is not a PEP 440 version")
# before building:
assert_pep440_version(project_version) Type guard
from packaging.version import Version, InvalidVersion
def is_pep440(v: str) -> bool:
try:
Version(v)
return True
except InvalidVersion:
return False Try / catch
from pip._internal.exceptions import UnsupportedWheel
try:
_verify_one(req, wheel_path)
except UnsupportedWheel as e:
if "mandates PEP 440" in str(e):
# fix version string in pyproject/setup
... Prevention
- Author versions per PEP 440 (`1.0a1`, `1.0rc1`, `1.0.post1`, `1.0.dev1`).
- Validate `Version(your_version)` in CI before building.
- Avoid dashes/`v` prefix in version literals.
When it happens
Trigger: `metadata_version >= Version('1.2')` and `not isinstance(dist.version, Version)` in `_verify_one`. Happens when a project declares `Metadata-Version: 1.2` (or higher) but its version string is non-PEP-440 (e.g. `1.0-alpha`, `1.0.dev1x`, legacy `1.0-1`).
Common situations: Projects with hand-written version strings not following PEP 440 (e.g. `1.0rc`, `1.0.0.beta`, dashes instead of PEP 440 separators); upgrading Metadata-Version without fixing the version; legacy packages re-packaged with modern metadata.
Related errors
- Invalid Metadata-Version: {metadata_version_value}
- Requested {ireq} has inconsistent version: expected {f_val!r
- Wheel has unexpected file name: expected {canonical_name!r},
- Wheel has unexpected file name: expected {dist_verstr!r}, go
- Missing Metadata-Version
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/5a5b4a0ab47fd10b.json.
Report an issue: GitHub.