dotnet/efcore · error · ValueError
Invalid Debian version format
Error message
Invalid Debian version format: {version} What it means
Raised by parse_debian_version (a ValueError) when the version string does not match '^(?:(\d+):)?([^-]+)(?:-(.+))$'. The regex requires a non-empty upstream part that contains no '-', and a numeric epoch. It is stricter than Debian policy, so it can reject real-world versions or, more commonly, a None/empty Version field from a malformed Packages index.
Solutions
- Identify which package/version triggers it: log the version string before parse_debian_version is called.
- Inspect the Packages index for entries with a missing or malformed Version field and exclude the offending package.
- Re-download the index in case it was truncated.
- Loosen the parser: guard against None/empty and accept dashes in the upstream portion per Debian policy.
Example fix
// before
def parse_debian_version(version):
match = re.match(r'^(?:(\d+):)?([^-]+)(?:-(.+))?$', version)
if not match:
raise ValueError(f"Invalid Debian version format: {version}")
// after
def parse_debian_version(version):
if not isinstance(version, str) or not version:
raise ValueError(f"Invalid Debian version format: {version!r}")
match = re.match(r'^(?:(\d+):)?(.+)$', version) # accept any non-empty body, split revision later
if not match:
raise ValueError(f"Invalid Debian version format: {version!r}") Defensive patterns
Strategy: validation
Validate before calling
# preflight: drop index entries with missing/blank Version before version comparison
packages, aliases = parse_package_index(content)
bad = [name for name, info in packages.items() if not info.get("Version")]
if bad:
sys.exit(f"Packages index has entries without Version (will crash version compare): {bad}") Prevention
- Filter out Packages entries missing Version/Filename/SHA256 right after parse_package_index.
- Re-download the index if it looks truncated (unparseable entries).
- Prefer a Debian-policy-compliant version parser over the strict regex if you hit exotic versions.
When it happens
Trigger: compare_debian_versions is called (during the 'keep highest version' step in parse_package_index, line 238) with a version string the regex rejects. Most often because Version is None (field missing in the entry) or empty.
Common situations: A Packages index entry missing its Version field, a truncated/partial index, a corrupt mirror, or an exotic version (epoch not numeric, upstream containing only dashes) the regex refuses.
Related errors
- A call was made to ' ' that changed an option that must be…
- Required properties ' ' are missing for the instance of…
- Required properties ' ' are missing for the instance of…
- Specified argument was out of the range of valid values…
- The context class name
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/b8e239f0856cb36c.
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 3a2006ef56)