pypa/pip · error · UnsupportedWheel

Error decoding metadata for

Error message

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

What it means

Raised as UnsupportedWheel from InMemoryMetadata.get_metadata in pkg_resources.py:63-70. When decoding a metadata file stored in the in-memory dict for a wheel, a UnicodeDecodeError on .decode() is wrapped with the wheel name and file name, because non-UTF-8 metadata in a wheel is unsupported.

Solutions

  1. Use a different wheel/source whose metadata is UTF-8.
  2. Rebuild the wheel ensuring all metadata files are UTF-8 encoded.
  3. If the package is yours, fix the source of the non-UTF-8 content.
Defensive patterns

Strategy: try-catch

Validate before calling

// Before reading in-memory wheel metadata, confirm UTF-8 decode:
for name, data in metadata_dict.items():
    data.decode('utf-8')  # raises early if a file is not UTF-8

Try / catch

from pip._internal.exceptions import UnsupportedWheel
try:
    meta = in_memory.get_metadata('METADATA')
except UnsupportedWheel as e:
    if 'Error decoding metadata' in str(e):
        # use an alternative wheel / rebuild
        ...

Prevention

When it happens

Trigger: Distribution.from_wheel reads wheel metadata via read_wheel_metadata_file into InMemoryMetadata; later get_metadata(name) calls .decode() on the bytes and raises UnicodeDecodeError, re-raised as UnsupportedWheel.

Common situations: A wheel containing metadata files encoded in a non-UTF-8 charset; a corrupted wheel whose metadata bytes are not valid UTF-8; a build tool that wrote non-UTF-8 text into METADATA.

Related errors


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

Appendix: 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 f399c37189)