dotnet/yarp · error · ValueError
Invalid Debian version format: {version}
Error message
Invalid Debian version format: {version} What it means
This ValueError is raised in parse_debian_version when a version string does not match the regex '^(?:(\d+):)?([^-]+)(?:-(.+))$'. The regex decomposes a Debian version into an optional numeric epoch (followed by colon), an upstream version (no hyphens), and an optional revision (after the last hyphen). The regex fails on empty strings, strings starting with a hyphen, or strings where nothing precedes the first hyphen. Debian policy guarantees well-formed versions have at least one non-hyphen character before any revision separator, so this error indicates genuinely malformed version data in the Packages index.
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 bd11867bee)
Solutions
- Print the offending version string (add logging before the regex match) to see exactly what failed.
- Inspect the Packages index around the package whose version caused the failure -- look for field corruption or misalignment.
- Re-download the package index to rule out truncation or decompression corruption.
- If the version comes from a third-party repository, normalise or skip non-Debian-format versions before passing to parse_debian_version.
- Broaden the regex if you need to handle non-standard versions: split on the last hyphen instead of using [^-]+.
- Validate version strings with a pre-check (try matching the regex) and log a warning + skip rather than crashing the entire build.
Example fix
# before -- crashes on any malformed version
match = re.match(r'^(?:(\d+):)?([^-]+)(?:-(.+))?$', version)
if not match:
raise ValueError(f"Invalid Debian version format: {version}")
# after -- split on last hyphen for robustness, warn on unexpected formats
if '-' in version:
upstream, revision = version.rsplit('-', 1)
if ':' in upstream:
epoch_str, upstream = upstream.split(':', 1)
epoch = int(epoch_str) if epoch_str.isdigit() else 0
else:
epoch = 0
else:
epoch, upstream, revision = 0, version, ""
if not upstream:
raise ValueError(f"Invalid Debian version format: {version}") Defensive patterns
Strategy: validation
Validate before calling
# Pre-validate version strings before parsing.
import re
_DEBIAN_VERSION_RE = re.compile(r'^(?:(\d+):)?([^-]+)(?:-(.+))?$')
def is_valid_debian_version(version):
return bool(version) and bool(_DEBIAN_VERSION_RE.match(version)) Type guard
# Validate and return None for invalid versions instead of raising
def safe_parse_version(version):
if not version or not isinstance(version, str):
return None
match = re.match(r'^(?:(\d+):)?([^-]+)(?:-(.+))?$', version)
if not match:
return None
epoch, upstream, revision = match.groups()
return (int(epoch) if epoch else 0, upstream, revision or "") Try / catch
# Wrap version comparison in try-except and skip bad entries
try:
if compare_debian_versions(version, existing_version) > 0:
packages[package_name] = {...}
except ValueError as e:
print(f"WARNING: {e}. Skipping package '{package_name}'.")
continue Prevention
- Validate version strings with a regex pre-check before passing to parse_debian_version.
- Log and skip malformed versions rather than crashing the entire build.
- Sanitise version data from third-party or non-standard repositories before parsing.
- Test the version parser against known-good Debian versions to ensure the regex is correct.
- If handling non-Debian formats, split on the last hyphen (rsplit) instead of using [^-]+ for robustness.
When it happens
Trigger: parse_debian_version (lines 156-160) is called from compare_debian_versions (lines 184-185), which is called from parse_package_index (line 238) to compare versions when selecting the highest version of a package. The ValueError fires if any package's Version field in the Packages index is empty, starts with '-', or is otherwise malformed. It can also fire if a Version field was parsed incorrectly due to the regex in parse_package_index capturing unexpected whitespace or multi-line values.
Common situations: A package entry in the Packages index has a missing or empty Version field (malformed index or download corruption); a version string from a non-Debian source (e.g. a PPA or third-party repo) uses a format the regex rejects; the Packages.gz decompression produced garbled output (truncation, encoding mismatch); a continuation line in the Packages index was misinterpreted, merging fields and corrupting the Version value; an epoch value contains non-digits.
Related errors
- SHA256 mismatch for {path}: expected {packages_sha}, got {sh
- Could not find checksum for {path} in Release file.
- SHA256 mismatch for {url}: expected {checksum}, got {sha256}
- Failed to download {url}, Status Code: {response.status}
- Failed to download {url} after {max_retries} attempts.
AI-assisted analysis of dotnet/yarp@bd11867bee (2026-08-13).
Data as JSON: /api/errors/9689c5262af1b688.
Report an issue: GitHub.