pypa/pip · error · InvalidSdistFilename
Invalid sdist filename (invalid version)
Error message
Invalid sdist filename (invalid version): {filename!r} What it means
Raised by parse_sdist_filename() when the version portion (after the last dash in the stem) cannot be parsed by Version() (utils.py:363-368). The inner InvalidVersion is caught and re-raised as InvalidSdistFilename. The version must conform to PEP 440.
Solutions
- Verify the version segment (after the last dash) is a valid PEP 440 version.
- Test the version with Version(version_str) in isolation to see the exact parse failure.
- If the project name contains a dash, note that rpartition splits on the LAST dash, so dashes in the name are fine but the version must be dash-free.
Example fix
// before
parse_sdist_filename('foo-latest.tar.gz')
// after
parse_sdist_filename('foo-1.0.tar.gz') Defensive patterns
Strategy: try-catch
Validate before calling
from packaging.version import Version, InvalidVersion
def safe_parse_sdist(filename: str):
stem = filename[:-7] if filename.endswith(".tar.gz") else filename[:-4]
_, _, version_part = stem.rpartition("-")
try:
Version(version_part)
except InvalidVersion:
raise ValueError(f"Invalid version {version_part!r} in sdist {filename!r}")
return parse_sdist_filename(filename) Type guard
from packaging.version import Version
def has_valid_sdist_version(filename: str) -> bool:
if not isinstance(filename, str):
return False
if filename.endswith(".tar.gz"):
stem = filename[:-7]
elif filename.endswith(".zip"):
stem = filename[:-4]
else:
return False
_, sep, version_part = stem.rpartition("-")
if not sep:
return False
try:
Version(version_part)
return True
except Exception:
return False Try / catch
from packaging.utils import InvalidSdistFilename
try:
name, ver = parse_sdist_filename(filename)
except InvalidSdistFilename as e:
if "invalid version" in str(e):
logger.error("Sdist version is not PEP 440 compliant: %s", filename)
raise Prevention
- Test the version segment with Version() in isolation first
- Note that rpartition splits on the LAST dash, so the version must be dash-free
- Ensure version strings are PEP 440 compliant before naming the sdist
When it happens
Trigger: An sdist filename where the version segment is not a valid PEP 440 version, e.g. parse_sdist_filename('foo-latest.tar.gz') where 'latest' fails Version() parsing.
Common situations: A version like 'latest', 'snapshot', or a non-numeric tag, or a version scheme that deviates from PEP 440. Also seen when the filename has a name containing a dash so rpartition splits at the wrong position.
Related errors
- Invalid wheel filename (invalid version)
- dev must be non-negative integer, got
- epoch must be non-negative integer, got
- Invalid sdist filename (empty project name)
- Invalid sdist filename (extension must be '.tar.gz' or…
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/f65982e3e6d8cf47.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_vendor/packaging/utils.py:366
f" {filename!r}"
)
# We are requiring a PEP 440 version, which cannot contain dashes,
# so we split on the last dash.
name_part, sep, version_part = file_stem.rpartition("-")
if not sep:
raise InvalidSdistFilename(f"Invalid sdist filename: {filename!r}")
if not name_part:
raise InvalidSdistFilename(
f"Invalid sdist filename (empty project name): {filename!r}"
)
name = canonicalize_name(name_part)
try:
version = Version(version_part)
except InvalidVersion as e:
raise InvalidSdistFilename(
f"Invalid sdist filename (invalid version): {filename!r}"
) from e
return (name, version)
View on GitHub (pinned to f399c37189)