pypa/pip · error · UnsupportedWheel

Error decoding metadata for {self._wheel_name}: {e} in {name

Error message

Error decoding metadata for {self._wheel_name}: {e} in {name} file

What it means

UnsupportedWheel raised by InMemoryMetadata.get_metadata() (pkg_resources backend) when a metadata file's bytes cannot be decoded (UnicodeDecodeError). Mirrors the importlib-backend equivalent: the wheel is a valid zip but a metadata file is not decodable as text.

Source

Thrown at src/pip/_internal/metadata/pkg_resources.py:68

class InMemoryMetadata:
    """IMetadataProvider that reads metadata files from a dictionary.

    This also maps metadata decoding exceptions to our internal exception type.
    """

    def __init__(self, metadata: Mapping[str, bytes], wheel_name: str) -> None:
        self._metadata = metadata
        self._wheel_name = wheel_name

    def has_metadata(self, name: str) -> bool:
        return name in self._metadata

    def get_metadata(self, name: str) -> str:
        try:
            return self._metadata[name].decode()
        except UnicodeDecodeError as e:
            # Augment the default error with the origin of the file.
            raise UnsupportedWheel(
                f"Error decoding metadata for {self._wheel_name}: {e} in {name} file"
            )

    def get_metadata_lines(self, name: str) -> Iterable[str]:
        return pkg_resources.yield_lines(self.get_metadata(name))

    def metadata_isdir(self, name: str) -> bool:
        return False

    def metadata_listdir(self, name: str) -> list[str]:
        return []

    def run_script(self, script_name: str, namespace: str) -> None:
        pass


class Distribution(BaseDistribution):
    def __init__(self, dist: pkg_resources.Distribution) -> None:

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Rebuild the wheel with a current backend that emits UTF-8 metadata.
  2. Re-download the wheel from PyPI (verify hash) to rule out corruption.
  3. Install from sdist (--no-binary) to bypass the wheel.
  4. Report to the maintainer if a published wheel is affected.

Example fix

# before
pip install somepkg-1.0-py2.py3-none-any.whl  # legacy latin-1 METADATA

# after
pip install --no-binary somepkg somepkg
# or rebuild
python -m build --wheel
Defensive patterns

Strategy: validation

Validate before calling

import zipfile
with zipfile.ZipFile(wheel_path) as zf:
    info_dir = next(n.split('/')[0] for n in zf.namelist() if n.endswith('.dist-info/METADATA'))
    data = zf.read(f'{info_dir}/METADATA')
    try:
        data.decode('utf-8')
    except UnicodeDecodeError:
        print(f'METADATA in {wheel_path} not UTF-8')

Type guard

def wheel_metadata_decodable(path: str) -> bool:
    import zipfile
    try:
        with zipfile.ZipFile(path) as zf:
            for n in zf.namelist():
                if n.endswith(('.dist-info/METADATA', '.dist-info/WHEEL')):
                    zf.read(n).decode('utf-8')
        return True
    except (UnicodeDecodeError, zipfile.BadZipFile):
        return False

Try / catch

from pip._internal.exceptions import UnsupportedWheel
try:
    dist = Distribution.from_wheel(wheel, name)
except UnsupportedWheel as e:
    if 'decoding metadata' in str(e):
        # rebuild/re-download wheel; fall back to sdist
        ...

Prevention

When it happens

Trigger: Reached when get_metadata(name) calls self._metadata[name].decode() and the bytes are not valid UTF-8 (default decode). The wheel name and offending file are included in the message.

Common situations: A legacy wheel whose METADATA/entry_points were written in a non-UTF-8 encoding; a corrupt wheel; a wheel produced by an old setuptools on a non-UTF-8 locale.

Related errors


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