{"record":{"id":"ea7261baa6c9cec3","repo":"dotnet/aspnetcore","slug":"invalid-debian-version-format-version","errorCode":null,"errorMessage":"Invalid Debian version format: {version}","messagePattern":"Invalid Debian version format: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"eng/common/cross/install-debs.py","lineNumber":160,"sourceCode":"def parse_release_file(content, path):\n    \"\"\"Parses the Release file and returns sha256 checksum of the specified path.\"\"\"\n\n    # data looks like this:\n    # <checksum>  <size>  <path>\n    matches = re.findall(r'^ (\\S*) +(\\S*) +(\\S*)$', content, re.MULTILINE)\n\n    for entry in matches:\n        # the file has both md5 and sha256 checksums, we want sha256 which has a length of 64\n        if entry[2] == path and len(entry[0]) == 64:\n            return entry[0]\n\n    raise Exception(f\"Could not find checksum for {path} in Release file.\")\n\ndef parse_debian_version(version):\n    \"\"\"Parse a Debian package version into epoch, upstream version, and revision.\"\"\"\n    match = re.match(r'^(?:(\\d+):)?([^-]+)(?:-(.+))?$', version)\n    if not match:\n        raise ValueError(f\"Invalid Debian version format: {version}\")\n    epoch, upstream, revision = match.groups()\n    return int(epoch) if epoch else 0, upstream, revision or \"\"\n\ndef compare_upstream_version(v1, v2):\n    \"\"\"Compare upstream or revision parts using Debian rules.\"\"\"\n    def tokenize(version):\n        tokens = re.split(r'([0-9]+|[A-Za-z]+)', version)\n        return [int(x) if x.isdigit() else x for x in tokens if x]\n\n    tokens1 = tokenize(v1)\n    tokens2 = tokenize(v2)\n\n    for token1, token2 in zip(tokens1, tokens2):\n        if type(token1) == type(token2):\n            if token1 != token2:\n                return (token1 > token2) - (token1 < token2)\n        else:\n            return -1 if isinstance(token1, str) else 1","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/eng/common/cross/install-debs.py#L142-L178","documentation":"parse_debian_version applies the regex ^(?:(\\d+):)?([^-]+)(?:-(.+))?$ to a version string and raises ValueError if it does not match. This parser underpins compare_debian_versions used to pick the highest version of each package from the index. Debian versions are normally epoch:upstream-revision, but malformed entries (empty string, version starting with '-', containing only a hyphen, etc.) break the regex.","triggerScenarios":"parse_package_index extracts Version fields from Packages.gz entries and calls compare_debian_versions whenever a package name already has a recorded version. If a mirror's Packages.gz contains a corrupt/empty Version field, the regex fails and ValueError is raised. Also triggered by manually feeding a non-Debian version string into the comparator.","commonSituations":"Corrupt or partial Packages.gz download that produced garbage Version fields; a mirror shipping a test/development package with a non-conformant version; an upstream package whose versioning violates Debian policy.","solutions":["Re-download the Packages.gz from a clean mirror — corruption during fetch is the usual cause.","Verify the --mirror and --suite produce a well-formed Packages.gz (open it and grep for 'Version:' lines).","If a single malformed package is to blame, exclude it from the requested package list or filter it before parse_package_index.","Inspect the offending version string in the exception message to determine whether it is empty, hyphen-only, or otherwise non-Debian."],"exampleFix":"# before — corrupt Packages.gz from a flaky mirror\npython3 install-debs.py --mirror http://bad-mirror/debian --suite sid ...\n# ValueError: Invalid Debian version format: \n\n# after\npython3 install-debs.py --mirror http://deb.debian.org/debian --suite sid ...","handlingStrategy":"validation","validationCode":"# Pre-validate version strings before feeding them to compare_debian_versions\nimport re\nDEB_VERSION_RE = re.compile(r'^(?:(\\d+):)?([^-]+)(?:-(.+))?$')\ndef is_valid_debian_version(v: str) -> bool:\n    return bool(v) and bool(DEB_VERSION_RE.match(v))\n\nfor name, info in packages.items():\n    v = info.get('Version')\n    if not is_valid_debian_version(v):\n        print(f'Skipping {name}: malformed Version {v!r}')\n        continue","typeGuard":"import re\n_DEB_VERSION_RE = re.compile(r'^(?:(\\d+):)?([^-]+)(?:-(.+))?$')\ndef is_valid_debian_version(v: object) -> bool:\n    return isinstance(v, str) and bool(v) and bool(_DEB_VERSION_RE.match(v))","tryCatchPattern":"try:\n    epoch, upstream, revision = parse_debian_version(version)\nexcept ValueError as e:\n    if 'Invalid Debian version format' in str(e):\n        print(f'Skipping entry with malformed version {version!r}; re-download Packages.gz')\n        continue\n    raise","preventionTips":["Re-download Packages.gz from a clean mirror if versions look malformed.","Validate Version fields before comparing to fail soft rather than aborting the whole build.","Log offending versions to identify the corrupt mirror entry.","Sanitize Versions from non-official repositories before parsing."],"tags":["python","debian","versioning","parsing","install-debs","rootfs"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}