pypa/pip · error · KeyError
No metadata except PKG-INFO is available
Error message
No metadata except PKG-INFO is available
What it means
Raised as KeyError by FileMetadata.get_metadata(name). FileMetadata is an EmptyProvider subclass backed by a single file path (a PKG-INFO file); it deliberately serves only the 'PKG-INFO' metadata name and rejects any other name. has_metadata() on the same class returns True only for name == 'PKG-INFO'. It is constructed when only a bare PKG-INFO path is available (e.g. an old-style source dist or a single metadata file).
Source
Thrown at src/pip/_vendor/pkg_resources/__init__.py:2171
metadata = FileMetadata("/path/to/PKG-INFO")
This provider rejects all data and metadata requests except for PKG-INFO,
which is treated as existing, and will be the contents of the file at
the provided location.
"""
def __init__(self, path: StrPath):
self.path = path
def _get_metadata_path(self, name):
return self.path
def has_metadata(self, name: str) -> bool:
return name == 'PKG-INFO' and os.path.isfile(self.path)
def get_metadata(self, name: str):
if name != 'PKG-INFO':
raise KeyError("No metadata except PKG-INFO is available")
with open(self.path, encoding='utf-8', errors="replace") as f:
metadata = f.read()
self._warn_on_replacement(metadata)
return metadata
def _warn_on_replacement(self, metadata):
replacement_char = '�'
if replacement_char in metadata:
tmpl = "{self.path} could not be properly decoded in UTF-8"
msg = tmpl.format(**locals())
warnings.warn(msg)
def get_metadata_lines(self, name: str) -> Iterator[str]:
return yield_lines(self.get_metadata(name))
class PathMetadata(DefaultProvider):View on GitHub (pinned to d7d0d0a394)
Solutions
- Guard with has_metadata() first: `if dist.has_metadata(name): dist.get_metadata(name)`.
- If you need full metadata, point the distribution at a complete .dist-info/.egg-info directory (use PathMetadata or DistInfoMetadata) instead of a single PKG-INFO file.
- Use importlib.metadata, which returns at least core metadata for installed dists and degrades more gracefully.
Example fix
// before
ep_text = dist.get_metadata('entry_points.txt') # KeyError: only PKG-INFO available
// after
if dist.has_metadata('entry_points.txt'):
ep_text = dist.get_metadata('entry_points.txt')
else:
ep_text = '' # no entry points metadata present Defensive patterns
Strategy: validation
Validate before calling
def safe_get_metadata(dist, name):
if dist.has_metadata(name):
return dist.get_metadata(name)
return None # or raise a domain-specific error Type guard
def metadata_available(dist, name) -> bool:
return dist.has_metadata(name) Try / catch
try:
text = dist.get_metadata(name)
except KeyError as e:
if 'PKG-INFO' in str(e):
text = None # only PKG-INFO is available on FileMetadata
else:
raise Prevention
- Always guard get_metadata with has_metadata(name).
- Point distributions at full .dist-info/.egg-info dirs, not lone PKG-INFO files.
- Use importlib.metadata for installed-distribution metadata lookups.
When it happens
Trigger: Calling dist.get_metadata('entry_points.txt') (or RECORD, requires.txt, etc.) on a Distribution whose metadata provider is a FileMetadata — i.e. it was built from a lone PKG-INFO file rather than a full .egg-info/.dist-info directory. Any name != 'PKG-INFO' raises KeyError.
Common situations: Old-style distributions or sdist layouts that ship only a PKG-INFO; tools that construct a Distribution from a single metadata file; querying rich metadata (entry points, dependencies) from a source that never had it.
Related errors
- Error decoding metadata for {self._wheel_name}: {e} in {name
- Expected str, Requirement, or Distribution
- Script {script!r} not found in metadata at {self.egg_info!r}
- `base` parameter in `_fn` is `None`. Either override this me
- Invalid group name
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/c6f6e1e20c4bb11b.json.
Report an issue: GitHub.