dotnet/runtime · error · ValueError
Invalid Debian version format: {version}
Error message
Invalid Debian version format: {version} What it means
Raised by parse_debian_version() in install-debs.py when a Debian package version string fails to match the regex '^(?:(\d+):)?([^-]+)(?:-(.+))$'. This regex expects an optional numeric epoch prefix (colon-separated), a mandatory upstream version, and an optional hyphen-separated revision. The function is called transitively from parse_package_index() via compare_debian_versions() to select the highest available package version during rootfs creation.
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 60108ba66e)
Solutions
- Inspect the downloaded Packages index for the offending version string by grepping for 'Version:' lines and checking for malformed entries.
- Verify the --suite and --mirror arguments point to a valid Debian-compatible repository that follows Debian version policy.
- If the version is valid per Debian policy but the regex is too strict, extend the regex in parse_debian_version() to handle the edge case.
- Switch to a different mirror or suite that provides well-formed package metadata.
Example fix
# before
match = re.match(r'^(?:(\d+):)?([^-]+)(?:-(.+))?$', version)
if not match:
raise ValueError(f"Invalid Debian version format: {version}")
# after - allow colon in upstream version for epoch-like native versions
match = re.match(r'^(?:(\d+):)?(.+?)(?:-([^-]+))?$', version)
if not match:
raise ValueError(f"Invalid Debian version format: {version}") Defensive patterns
Strategy: validation
Validate before calling
import re
def is_valid_debian_version(version: str) -> bool:
"""Check if a version string matches Debian version format before passing to parse_debian_version."""
return re.match(r'^(?:(\d+):)?([^-]+)(?:-(.+))?$', version) is not None
# Usage before calling compare_debian_versions:
if not is_valid_debian_version(version_str):
print(f"Warning: skipping malformed version: {version_str}")
continue Type guard
null
Try / catch
try:
epoch, upstream, revision = parse_debian_version(version)
except ValueError as e:
logging.warning(f"Skipping package with unparseable version: {e}")
continue # skip this package rather than aborting the entire rootfs build Prevention
- Validate version strings from external sources before parsing.
- Log the raw version string when parsing fails for post-mortem analysis.
- Pin to known-good mirror/suite combinations that produce standard Debian versions.
- Add unit tests for parse_debian_version covering edge cases like epoch, native, and empty revision.
When it happens
Trigger: Triggered when the Packages.gz index downloaded from the Debian/Ubuntu mirror contains a Version field that the regex cannot parse. For example, a version like '1:1.2:3' (multiple colons), an empty upstream segment like ':1.2.3', or a version containing only a revision with no upstream part. The call chain is parse_package_index -> compare_debian_versions -> parse_debian_version.
Common situations: Happens when the mirror returns package metadata with non-standard version strings, when a custom or exotic distribution uses a non-Debian versioning scheme, or when the Packages index is truncated/corrupted mid-download. Also possible when the mirror serves packages from a suite with native versioning that deviates from Debian policy (e.g., some embedded or ports repositories).
Related errors
- Could not find 'data.tar.*' in {deb_file}.
- Unsupported compression format: {file_extension}
- event must be an object, but got ${JSON.stringify(event)}
- event.eventName is a required parameter, in event: ${JSON.st
- args must be an object, but got ${JSON.stringify(args)}
AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10).
Data as JSON: /api/errors/93cb8c3234b4dfc3.
Report an issue: GitHub.