pypa/pip · error · PylockValidationError

Version in is not consistent with package version

Error message

Version in {package.sdist.filename!r} is not consistent with package version {str(package.version)!r}

What it means

PylockValidationError: the version parsed from an sdist filename differs from package.version (only checked when package.version is set). Guarantees the source tarball corresponds to the pinned release.

Solutions

  1. Read the version segment of sdist.filename and compare to package.version.
  2. Replace the sdist filename so its version equals the declared package version.
  3. Regenerate the lock to keep sdist filename and version in lockstep.
  4. Re-validate.

Example fix

# before
[[packages]]
name = "requests"
version = "2.31.0"
  [packages.sdist]
  filename = "requests-2.30.0.tar.gz"

# after
[[packages]]
name = "requests"
version = "2.31.0"
  [packages.sdist]
  filename = "requests-2.31.0.tar.gz"
Defensive patterns

Strategy: validation

Validate before calling

from packaging.utils import parse_sdist_filename
from packaging.version import Version

def sdist_version_consistent(filename: str, version: str) -> bool:
    try:
        _, ver = parse_sdist_filename(filename)
    except Exception:
        return False
    return not version or Version(str(ver)) == Version(version)

for p in toml_dict.get('packages', []):
    s = p.get('sdist') or {}
    if s:
        assert sdist_version_consistent(s['filename'], p.get('version')), s['filename']

Type guard

null

Try / catch

try:
    Pylock.from_dict(toml_dict)
except PylockValidationError as e:
    # e.context == 'sdist'; align sdist version with package.version
    report(e.context, e.message)

Prevention

When it happens

Trigger: Package validation compares the version from parse_sdist_filename to package.version. Fires when version='2.31.0' but sdist.filename='requests-2.30.0.tar.gz', e.g. an old tarball left after a version bump.

Common situations: Partial lock update bumping the version field but leaving the sdist filename; a stale sdist cached by a buggy locker; an sdist rebuilt under a dev/local version that normalizes apart from the pinned one.

Related errors


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

Appendix: source

Thrown at src/pip/_vendor/packaging/pylock.py:648

                    f"package version {str(package.version)!r}",
                    context=f"wheels[{i}]",
                )
        if package.sdist:
            try:
                name, version = parse_sdist_filename(package.sdist.filename)
            except Exception as e:
                raise PylockValidationError(
                    f"Invalid sdist filename {package.sdist.filename!r}",
                    context="sdist",
                ) from e
            if name != package.name:
                raise PylockValidationError(
                    f"Name in {package.sdist.filename!r} is not consistent with "
                    f"package name {package.name!r}",
                    context="sdist",
                )
            if package.version and version != package.version:
                raise PylockValidationError(
                    f"Version in {package.sdist.filename!r} is not consistent with "
                    f"package version {str(package.version)!r}",
                    context="sdist",
                )
        try:
            for i, attestation_identity in enumerate(  # noqa: B007
                package.attestation_identities or []
            ):
                _get_required(attestation_identity, str, "kind")
        except Exception as e:
            raise PylockValidationError(
                e, context=f"attestation-identities[{i}]"
            ) from e
        return package

    @property
    def is_direct(self) -> bool:
        return not (self.sdist or self.wheels)

View on GitHub (pinned to f399c37189)