dotnet/aspnetcore · error · ValueError
Invalid Debian version format
Error message
Invalid Debian version format: {version} What it means
Raised as a ValueError by parse_debian_version when a version string does not match the regex ^(?:(\d+):)?([^-]+)(?:-(.+))?$. The regex is permissive (epoch optional, upstream part is any non-dash run, revision optional), so a failure means the version is empty, starts with '-', or contains a character class the regex does not accept for the upstream segment.
Solutions
- Inspect the Packages.gz content for the package named in the error context — `apt-cache showsrc <pkg>` against the same mirror, or gunzip and grep the local index for the Version line.
- If the mirror has a malformed entry, switch --mirror or --suite to one with a well-formed index.
- Pre-filter parsed packages in parse_package_index to skip entries whose Version does not match the regex, so one bad row does not abort the whole run.
- If you control the input, normalize version strings upstream to the canonical Debian form epoch:upstream-revision.
Example fix
# before: malformed Version in index breaks parse_debian_version
# (e.g. Version: -1 in a custom Packages file)
# after: guard in parse_package_index before inserting
version = fields.get("Version")
if not version or not re.match(r'^(?:(\d+):)?([^-]+)(?:-(.+))?$', version):
print(f"Skipping {package_name}: invalid Version '{version}'")
continue Defensive patterns
Strategy: validation
Validate before calling
# Before the comparison step, scan the parsed index for malformed Version fields:
gunzip -c "$MIRROR/dists/$SUITE/main/binary-$ARCH/Packages.gz" | awk 'BEGIN{RS=""}/^Version: [^:A-Za-z0-9.+~-]/||/^Version: $/{print "bad:",$0}' Type guard
import re
VALID_VERSION = re.compile(r'^(?:(\d+):)?([^-]+)(?:-(.+))?$')
def is_valid_debian_version(v: str | None) -> bool:
return bool(v) and bool(VALID_VERSION.match(v)) Prevention
- Pre-filter Packages entries whose Version does not match the canonical regex before insert into the dict.
- Switch --suite / --mirror when the index contains malformed rows.
- If you feed in versions directly, normalize them to epoch:upstream-revision.
When it happens
Trigger: compare_debian_versions calls parse_debian_version on both arguments; parse_package_index reads Version from Packages entries and then compares them via compare_debian_versions. A malformed Version field in the Packages index (or a None passed through) reaches the regex and fails to match.
Common situations: Packages entry has an empty Version field or one with an unusual epoch like ':' with no digits; a hand-edited or partially-local Packages index; native vs non-native versioning edge case where upstream contains characters the regex's [^-]+ still allows but the surrounding groups trip on; None reaching the function because parse_package_index's regex didn't capture Version.
Related errors
- Could not find checksum for
- Could not find 'data.tar.*' in
- Failed to download after attempts.
- Failed to download , Status Code
- SHA256 mismatch for : expected , got
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/ea7261baa6c9cec3.
Report an issue: GitHub.
Appendix: source
Thrown at eng/common/cross/install-debs.py:160
def parse_release_file(content, path):
"""Parses the Release file and returns sha256 checksum of the specified path."""
# data looks like this:
# <checksum> <size> <path>
matches = re.findall(r'^ (\S*) +(\S*) +(\S*)$', content, re.MULTILINE)
for entry in matches:
# the file has both md5 and sha256 checksums, we want sha256 which has a length of 64
if entry[2] == path and len(entry[0]) == 64:
return entry[0]
raise Exception(f"Could not find checksum for {path} in Release file.")
def parse_debian_version(version):
"""Parse a Debian package version into epoch, upstream version, and revision."""
match = re.match(r'^(?:(\d+):)?([^-]+)(?:-(.+))?$', version)
if not match:
raise ValueError(f"Invalid Debian version format: {version}")
epoch, upstream, revision = match.groups()
return int(epoch) if epoch else 0, upstream, revision or ""
def compare_upstream_version(v1, v2):
"""Compare upstream or revision parts using Debian rules."""
def tokenize(version):
tokens = re.split(r'([0-9]+|[A-Za-z]+)', version)
return [int(x) if x.isdigit() else x for x in tokens if x]
tokens1 = tokenize(v1)
tokens2 = tokenize(v2)
for token1, token2 in zip(tokens1, tokens2):
if type(token1) == type(token2):
if token1 != token2:
return (token1 > token2) - (token1 < token2)
else:
return -1 if isinstance(token1, str) else 1View on GitHub (pinned to 3600ca084e)