{"record":{"id":"054441fb94ab4689","repo":"dotnet/runtime","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/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/eng/common/cross/install-debs.py#L314-L350","documentation":"Raised by extract_deb_file() in install-debs.py when the data.tar archive member inside a .deb has a file extension that is not .xz, .gz, or .zst. These are the only three compression formats the extraction logic handles. The .zst path decompresses using the zstandard library, .xz and .gz use Python's tarfile module with built-in decompression.","triggerScenarios":"Triggered when os.path.splitext(tar_file_path)[1] returns an extension other than '.xz', '.gz', or '.zst'. The tar filename comes from the 'ar t' listing of the .deb. Modern Debian uses .xz or .zst; older releases may use .gz. A new compression format or a non-standard member name would trigger this.","commonSituations":"A distribution adopts a new compression format not yet handled by the script (historically, .bz2 was used by older Debian releases). A .deb built with non-standard tooling produces a data.tar with an unexpected extension. The .deb uses .lzma or .bz2 which were once common.","solutions":["Check the tar filename from 'ar t' output to see what extension the data.tar member actually has.","Add a branch for the missing compression format (e.g., add '.bz2' with mode 'r:bz2' for tarfile, or handle '.lzma').","Use a different suite/mirror whose packages use a supported compression format.","Pre-decompress the data.tar externally and point the script at the uncompressed tar."],"exampleFix":"# before\nif file_extension == \".xz\":\n    mode = \"r:xz\"\nelif file_extension == \".gz\":\n    mode = \"r:gz\"\nelif file_extension == \".zst\":\n    ...\nelse:\n    raise ValueError(f\"Unsupported compression format: {file_extension}\")\n\n# after - add bz2 support\nif file_extension == \".xz\":\n    mode = \"r:xz\"\nelif file_extension == \".gz\":\n    mode = \"r:gz\"\nelif file_extension == \".bz2\":\n    mode = \"r:bz2\"\nelif file_extension == \".zst\":\n    ...\nelse:\n    raise ValueError(f\"Unsupported compression format: {file_extension}\")","handlingStrategy":"validation","validationCode":"import os\n\nSUPPORTED_EXTENSIONS = {'.xz', '.gz', '.zst'}\n\ndef get_supported_compression(tar_filename: str) -> str:\n    \"\"\"Check if the data.tar compression format is supported.\"\"\"\n    ext = os.path.splitext(tar_filename)[1].lower()\n    if ext not in SUPPORTED_EXTENSIONS:\n        raise ValueError(\n            f\"Unsupported compression '{ext}'. Supported: {SUPPORTED_EXTENSIONS}. \"\n            f\"You may need to pre-decompress the archive manually.\")\n    return ext","typeGuard":"null","tryCatchPattern":"try:\n    extract_deb_file(deb_file, tmp_dir, extract_dir, ar_tool)\nexcept ValueError as e:\n    if \"Unsupported compression\" in str(e):\n        # Attempt manual decompression as fallback\n        logging.warning(f\"{e}. Attempting manual extraction.\")\n        manual_extract_deb(deb_file, extract_dir)\n    else:\n        raise","preventionTips":["Check the suite/mirror documentation for what compression format their .deb files use.","Keep the supported extensions list in sync with current Debian packaging practices.","Add .bz2 support preemptively if working with older distributions.","Log the tar filename when extraction starts so the extension is visible on failure."],"tags":["debian","packaging","rootfs","compression","tar"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}