{"record":{"id":"36e0532410810b69","repo":"dotnet/efcore","slug":"unsupported-compression-format-file-extension","errorCode":null,"errorMessage":"Unsupported compression format: {file_extension}","messagePattern":"Unsupported compression format: (.+?)","errorType":"exception","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/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/eng/common/cross/install-debs.py#L314-L350","documentation":"Raised as ValueError by extract_deb_file after picking the data.tar member: os.path.splitext gives an extension that is not .xz, .gz, or .zst - the only three the function knows how to decompress. Any other extension (e.g. .bz2, .lzma) or an empty extension falls through to the else branch.","triggerScenarios":"extract_deb_file on a .deb whose data.tar member uses a compression the code does not handle - .tar.bz2 / .tar.lzma / uncompressed .tar - so os.path.splitext(tar_file_path)[1].lower() returns '.bz2'/'.lzma'/'/'.","commonSituations":"An older or niche distro/suite shipping .deb with bzip2-compressed data.tar; a third-party package using a non-standard compressor; a suite change where the distro switched formats and this script has not been updated.","solutions":["Identify the member name from `ar t <deb>` to see the exact compression (data.tar.bz2, data.tar.lzma, etc.).","Extend the if/elif chain in extract_deb_file to handle the new extension (e.g. '.bz2' -> mode 'r:bz2', available via the stdlib tarfile).","If you cannot edit the script, repackage the .deb so its data.tar uses .gz/.xz/.zst, or pick a --suite whose debs use a supported format.","Report the format upstream if a stock distro suite is shipping it - the script likely needs a one-line addition."],"exampleFix":"# before\n        if file_extension == \".xz\":\n            mode = \"r:xz\"\n        elif file_extension == \".gz\":\n            mode = \"r:gz\"\n        elif file_extension == \".zst\":\n            ...\n        else:\n            raise ValueError(f\"Unsupported compression format: {file_extension}\")\n# after (add bzip2 support)\n        if file_extension == \".xz\":\n            mode = \"r:xz\"\n        elif file_extension == \".gz\":\n            mode = \"r:gz\"\n        elif file_extension == \".bz2\":\n            mode = \"r:bz2\"\n        elif file_extension == \".zst\":\n            ...","handlingStrategy":"validation","validationCode":"# Validate the data.tar compression is supported before extract_deb_file decompresses\nimport subprocess, os\n\nSUPPORTED = {'.xz', '.gz', '.zst'}\n\ndef deb_uses_supported_compression(deb_file, ar_tool='ar'):\n    res = subprocess.run([ar_tool, 't', deb_file], capture_output=True, text=True, check=True)\n    member = next((l.strip() for l in res.stdout.splitlines() if l.startswith('data.tar')), None)\n    if not member:\n        raise RuntimeError(f\"{deb_file} has no data.tar member\")\n    ext = os.path.splitext(member)[1].lower()\n    if ext not in SUPPORTED:\n        raise RuntimeError(f\"{deb_file} uses {ext} for data.tar; supported: {sorted(SUPPORTED)}\")\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 format\" in str(e):\n        # either repackage the .deb to .gz/.xz or pick a suite that uses a supported format\n        raise SystemExit(f\"{e}. Add a branch in extract_deb_file or switch suite.\")\n    raise","preventionTips":["Before adopting a new distro/suite, sample one .deb and check `ar t` shows data.tar.{gz,xz,zst}.","Keep extract_deb_file's extension table in sync with formats the distros you target actually ship.","Unit-test extract_deb_file against .gz, .xz, and .zst fixtures so a format regression is caught early."],"tags":["archive","compression","extraction","deb"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}