{"record":{"id":"07c6e7e1c089d508","repo":"dotnet/aspnetcore","slug":"unsupported-compression-format-file-extension","errorCode":null,"errorMessage":"Unsupported compression format: {file_extension}","messagePattern":"Unsupported compression format: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"eng/common/cross/install-debs.py","lineNumber":332,"sourceCode":"            subprocess.run([ar_tool, \"p\", os.path.abspath(deb_file), tar_filename], check=True, stdout=outfile, stderr=subprocess.PIPE)\n\n        file_extension = os.path.splitext(tar_file_path)[1].lower()\n\n        if file_extension == \".xz\":\n            mode = \"r:xz\"\n        elif file_extension == \".gz\":\n            mode = \"r:gz\"\n        elif file_extension == \".zst\":\n            # zstd is not supported by standard library yet\n            decompressed_tar_path = tar_file_path.replace(\".zst\", \"\")\n            with open(tar_file_path, \"rb\") as zst_file, open(decompressed_tar_path, \"wb\") as decompressed_file:\n                dctx = zstandard.ZstdDecompressor()\n                dctx.copy_stream(zst_file, decompressed_file)\n\n            tar_file_path = decompressed_tar_path\n            mode = \"r\"\n        else:\n            raise ValueError(f\"Unsupported compression format: {file_extension}\")\n\n        with tarfile.open(tar_file_path, mode) as tar:\n            tar.extractall(path=extract_dir, filter=_rootfs_extraction_filter)\n\ndef _rootfs_extraction_filter(member, dest_path):\n    \"\"\"Tarfile extraction filter based on the 'data' filter that additionally\n    rewrites absolute-target symlinks/hardlinks into rootfs-relative paths.\n    \"\"\"\n    if (member.issym() or member.islnk()) and os.path.isabs(member.linkname):\n        link_dir = os.path.dirname(member.name)\n        new_linkname = os.path.relpath(member.linkname.lstrip('/'),\n                                       start=link_dir or '.')\n        member = member.replace(linkname=new_linkname, deep=False)\n    return tarfile.data_filter(member, dest_path)\n\ndef finalize_setup(rootfsdir):\n    lib_dir = os.path.join(rootfsdir, 'lib')\n    usr_lib_dir = os.path.join(rootfsdir, 'usr', 'lib')","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/eng/common/cross/install-debs.py#L314-L350","documentation":"extract_deb_file chooses a tarfile open mode based on the data.tar extension: .xz -> r:xz, .gz -> r:gz, .zst -> decompress via zstandard then r. Any other extension raises ValueError. This guards against a .deb using a compression the rootfs builder cannot decompress. Modern Debian is moving to .zst (zstd), which IS handled via the zstandard library, but more exotic formats (bz2, lz, lzma, or a future format) are not.","triggerScenarios":"The data.tar member inside the .deb has an extension other than .xz/.gz/.zst (e.g., .bz2, .lzma, .tar with no compression, or a doubly-suffixed name the os.path.splitext does not reduce correctly). The switch at install-debs.py:316-332 falls through to the else branch and raises.","commonSituations":"Older Ubuntu .debs that used .lzma; a custom/patched .deb with bz2 data.tar; a filename like 'data.tar.foo' from a non-standard archive tool; a misconfigured os.path.splitext on a double extension producing an unexpected suffix.","solutions":["Identify the actual extension: 'ar t <deb>' shows the data.tar member name; check its suffix.","Switch to a suite/mirror whose .debs use .xz or .zst (the supported set).","If you genuinely need .bz2/.lzma support, extend the switch to add 'r:bz2'/'r:lzma' modes — but prefer using a mainstream mirror.","Verify the .deb is from an official Debian/Ubuntu repository and not a hand-built package with a non-standard data.tar compression."],"exampleFix":"# before — suite ships .lzma data.tar\npython3 install-debs.py --suite old-distro ...\n# ValueError: Unsupported compression format: .lzma\n\n# after — use a suite with .xz/.zst debs\npython3 install-debs.py --suite bookworm ...\n\n# or extend support (if you must)\n# in extract_deb_file:\n#   elif file_extension == '.bz2':\n#       mode = 'r:bz2'\n#   elif file_extension == '.lzma':\n#       mode = 'r:xz'","handlingStrategy":"validation","validationCode":"# Pre-check the data.tar compression before extraction\nimport os\nSUPPORTED = {'.xz', '.gz', '.zst'}\ndef supported_data_tar_compression(deb_file: str, ar: str = 'ar') -> bool:\n    r = subprocess.run([ar, 't', os.path.abspath(deb_file)], capture_output=True)\n    for line in r.stdout.decode().splitlines():\n        if line.startswith('data.tar'):\n            return os.path.splitext(line.lower())[1] in SUPPORTED\n    return False","typeGuard":"SUPPORTED = {'.xz', '.gz', '.zst'}\ndef is_supported_compression(ext: str) -> bool:\n    return ext.lower() in SUPPORTED","tryCatchPattern":"try:\n    extract_deb_file(deb_file, tmp_dir, extract_dir, ar_tool)\nexcept ValueError as e:\n    if 'Unsupported compression format' in str(e):\n        ext = str(e).split(':')[-1].strip()\n        print(f'.deb uses {ext}; extend extract_deb_file or switch to a .xz/.zst suite')\n        raise\n    raise","preventionTips":["Prefer mainstream Debian/Ubuntu suites that use .xz or .zst for data.tar.","Extend the compression switch (r:bz2, r:lzma) only if a legacy suite is unavoidable.","Run 'ar t <deb>' in CI to detect unsupported data.tar formats early.","Document the supported compression set for anyone maintaining install-debs.py."],"tags":["python","debian","deb","compression","tarfile","install-debs","rootfs"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}