pypa/pip · error · UnsupportedWheel
has an invalid wheel
Error message
{name} has an invalid wheel, {e} What it means
Raised as UnsupportedWheel from Distribution.from_wheel in pkg_resources.py:150-151. After the wheel zip is opened successfully, parsing the dist-info metadata (parse_wheel / read_wheel_metadata_file) may raise UnsupportedWheel for various malformations; pip re-raises with the package name prefixed so the offending wheel is identified.
Solutions
- Use a properly built wheel from another source/version.
- Rebuild the wheel with a standard backend (setuptools/hatch/poetry) that emits the required dist-info files.
- Inspect the wheel with `unzip -l file.whl` to confirm it contains a valid .dist-info directory.
Defensive patterns
Strategy: try-catch
Validate before calling
// Before trusting a wheel, confirm it has a valid dist-info with METADATA/WHEEL:
import zipfile
with wheel.as_zipfile() as zf:
names = zf.namelist()
assert any(n.endswith('.dist-info/METADATA') for n in names), 'missing METADATA'
assert any(n.endswith('.dist-info/WHEEL') for n in names), 'missing WHEEL' Try / catch
from pip._internal.exceptions import UnsupportedWheel
try:
dist = Distribution.from_wheel(wheel, name)
except UnsupportedWheel as e:
if 'invalid wheel' in str(e):
# use a properly built wheel
... Prevention
- Build wheels with standard backends that emit full dist-info.
- Inspect wheels with `unzip -l` before relying on them.
- Run twine check on wheels before publishing.
When it happens
Trigger: Distribution.from_wheel in the pkg_resources backend: the zip opens fine but parse_wheel or read_wheel_metadata_file raises UnsupportedWheel (e.g. missing/invalid WHEEL or METADATA inside), caught and re-raised as UnsupportedWheel(f"{name} has an invalid wheel, {e}").
Common situations: A wheel missing the .dist-info directory or its METADATA/WHEEL files; a wheel with a malformed RECORD; a non-standard wheel built by a broken backend.
Related errors
- Error decoding metadata for
- could not read file
- .dist-info directory
- .dist-info directory not found
- Duplicate entry point
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/a00d671b2a7fc2f8.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_internal/metadata/pkg_resources.py:151
metadata=InMemoryMetadata(metadata_dict, filename),
project_name=project_name,
)
return cls(dist)
@classmethod
def from_wheel(cls, wheel: Wheel, name: str) -> BaseDistribution:
try:
with wheel.as_zipfile() as zf:
info_dir, _ = parse_wheel(zf, name)
metadata_dict = {
path.split("/", 1)[-1]: read_wheel_metadata_file(zf, path)
for path in zf.namelist()
if path.startswith(f"{info_dir}/")
}
except zipfile.BadZipFile as e:
raise InvalidWheel(wheel.location, name) from e
except UnsupportedWheel as e:
raise UnsupportedWheel(f"{name} has an invalid wheel, {e}")
dist = pkg_resources.DistInfoDistribution(
location=wheel.location,
metadata=InMemoryMetadata(metadata_dict, wheel.location),
project_name=name,
)
return cls(dist)
@property
def location(self) -> str | None:
return self._dist.location
@property
def installed_location(self) -> str | None:
egg_link = egg_link_path_from_location(self.raw_name)
if egg_link:
location = egg_link
elif self.location:
location = self.locationView on GitHub (pinned to f399c37189)