pypa/pip · error · BadMetadata

Bad metadata in {dist} (invalid metadata entry `version`)

Error message

Bad metadata in {dist} (invalid metadata entry `version`)

What it means

BadMetadata raised by Distribution.version (importlib backend) when the version string cannot be parsed - either the .dist-info name has no version separator and dist.version is not a usable string, or parse_version() receives a non-string. It indicates non-conformant version metadata.

Source

Thrown at src/pip/_internal/metadata/importlib/_dists.py:176

    def installed_location(self) -> str | None:
        if self._installed_location is None:
            return None
        return normalize_path(str(self._installed_location))

    @property
    def canonical_name(self) -> NormalizedName:
        return get_dist_canonical_name(self._dist)

    @property
    def version(self) -> Version:
        try:
            version = (
                parse_name_and_version_from_info_directory(self._dist)[1]
                or self._dist.version
            )
            return parse_version(version)
        except TypeError:
            raise BadMetadata(self._dist, reason="invalid metadata entry `version`")

    @property
    def raw_version(self) -> str:
        return self.metadata["Version"]

    def is_file(self, path: InfoPath) -> bool:
        return self._dist.read_text(str(path)) is not None

    def iter_distutils_script_names(self) -> Iterator[str]:
        # A distutils installation is always "flat" (not in e.g. egg form), so
        # if this distribution's info location is NOT a pathlib.Path (but e.g.
        # zipfile.Path), it can never contain any distutils scripts.
        if not isinstance(self._info_location, pathlib.Path):
            return
        for child in self._info_location.joinpath("scripts").iterdir():
            yield child.name

    def read_text(self, path: InfoPath) -> str:

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Reinstall the package from a clean source to regenerate standard metadata.
  2. Check the .dist-info directory name follows '<name>-<version>.dist-info' and METADATA has a valid PEP 440 'Version' field.
  3. Delete the malformed .dist-info directory and reinstall.
  4. Report to the maintainer if the published artifact is non-compliant.

Example fix

; before - mypkg.dist-info/METADATA
Metadata-Version: 2.1
Name: mypkg
; no Version line

; after
Metadata-Version: 2.1
Name: mypkg
Version: 1.0.0
Defensive patterns

Strategy: validation

Validate before calling

import importlib.metadata, re
from packaging.version import InvalidVersion
for d in importlib.metadata.distributions():
    v = d.version
    try:
        parse = type(v); str(v)
        __import__('packaging.version').Version(str(v))
    except (TypeError, InvalidVersion):
        print(f'bad version metadata in {d}')

Type guard

def has_valid_version(dist) -> bool:
    from packaging.version import Version, InvalidVersion
    v = getattr(dist, 'version', None)
    try:
        Version(str(v))
        return True
    except (TypeError, InvalidVersion):
        return False

Try / catch

from pip._internal.metadata.importlib._compat import BadMetadata
try:
    _ = dist.version
except BadMetadata as e:
    if 'version' in str(e):
        # reinstall the dist from a clean source
        ...

Prevention

When it happens

Trigger: Reached when parse_name_and_version_from_info_directory returns no version (info dir name lacks '-version') and self._dist.version is None/non-str, so parse_version(None) raises TypeError, caught and re-raised as BadMetadata.

Common situations: A .dist-info directory named without a version (e.g. just 'mypkg.dist-info') and a METADATA file with no/malformed Version header; metadata generated by a broken custom build; partial install leftover.

Related errors


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