{"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":"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/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/eng/common/cross/install-debs.py#L314-L350","documentation":"Raised as ValueError by extract_deb_file when the data.tar member's file extension is not one of .xz, .gz, or .zst. It guards tarfile.open against being called with an unknown mode; a different compression means the code has no decompressor wired up.","triggerScenarios":"os.path.splitext(tar_file_path)[1].lower() is compared against .xz/.gz/.zst and matches none — for example data.tar.bz2, data.tar.lzma, data.tar.lz4, or a member named data.tar with no compression extension at all.","commonSituations":"Older Debian releases shipped data.tar.lzma or data.tar.bz2; some embedded/ports distros produce uncompressed data.tar; the .deb was repacked with a non-standard compressor; filename has an unexpected case or suffix that os.path.splitext misparses (e.g. data.tar.gz handled correctly, but data.tar.Z fails).","solutions":["Run `ar t <deb>` to see the exact member name; the suffix in the error message tells you which compressor you need.","If it is .bz2/.lzma/.Z, add a branch in extract_deb_file (mirroring the .zst branch using a streaming decompressor) or pre-convert the .deb.","Switch --suite to one that ships data.tar.xz or data.tar.gz (modern Debian/Ubuntu suites do).","If you control the input, repack the .deb with a supported compressor: `ar -d data.tar.bz2 foo.deb && ar -r data.tar.xz foo.deb` after recompressing."],"exampleFix":"# before: data.tar.bz2 not handled -> 'Unsupported compression format: .bz2'\n\n# after: add a branch (or switch suite)\n# Option A: code change\nelif file_extension == \".bz2\":\n    mode = \"r:bz2\"\n# Option B: switch to a suite that ships .xz\npython3 install-debs.py --suite bookworm --mirror http://deb.debian.org/debian ...","handlingStrategy":"validation","validationCode":"# Enumerate data.tar compressions across the .debs you will download, fail early:\nfor f in tmp/*.deb; do\n  ext=$(ar t \"$f\" | awk '/^data\\.tar/{print substr($0, index($0,\".\"))}')\n  case \"$ext\" in .xz|.gz|.zst) ;; *) echo \"unsupported $ext in $f\"; exit 1;; esac\ndone","typeGuard":"import os, subprocess\nSUPPORTED = {'.xz', '.gz', '.zst'}\ndef deb_compression_supported(deb: str) -> bool:\n    r = subprocess.run(['ar', 't', deb], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)\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","tryCatchPattern":null,"preventionTips":["Prefer modern suites (bookworm+, jammy+) that ship data.tar.xz.","If you must handle .bz2/.lzma, extend extract_deb_file with a matching branch (mode 'r:bz2' / streaming lzma).","Do not repack .debs with exotic compressors in your own pipeline."],"tags":["python","debian","archive","compression","tarfile","cross-build"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}