dotnet/efcore · error · ValueError

Unsupported compression format

Error message

Unsupported compression format: {file_extension}

What it means

Raised by extract_deb_file (a ValueError) when the data.tar member's file extension, taken via os.path.splitext, is not one of .xz, .gz, or .zst. tarfile.open needs a mode per compression, and the script only knows those three.

Solutions

  1. Run `ar t <deb_file>` to see the exact data.tar member name and its extension.
  2. If it is .bz2, add an `elif file_extension == '.bz2': mode = 'r:bz2'` branch.
  3. If it is an uncompressed .tar (or empty extension), add `elif file_extension in ('.tar',''): mode = 'r'`.
  4. For an unsupported format like .lzma, pre-decompress it manually (lzma -d) then point tarfile at the result.

Example fix

// before
if file_extension == ".xz": mode = "r:xz"
elif file_extension == ".gz": mode = "r:gz"
elif file_extension == ".zst": ...
else: raise ValueError(f"Unsupported compression format: {file_extension}")

// after
if file_extension == ".xz": mode = "r:xz"
elif file_extension == ".gz": mode = "r:gz"
elif file_extension == ".zst": ...
elif file_extension == ".bz2": mode = "r:bz2"
elif file_extension in (".tar", ""): mode = "r"
else: raise ValueError(f"Unsupported compression format: {file_extension}")
Defensive patterns

Strategy: validation

Validate before calling

# preflight: enumerate data.tar members across all debs and ensure each extension is supported
import subprocess
supported = {".xz", ".gz", ".zst"}
for deb in deb_files:
    members = subprocess.run([ar_tool, "t", deb], capture_output=True, text=True).stdout.split()
    exts = {os.path.splitext(m)[1].lower() for m in members if m.startswith("data.tar")}
    if not exts <= supported:
        sys.exit(f"{deb} uses unsupported data.tar compression {exts - supported}")

Prevention

When it happens

Trigger: The data.tar member inside the .deb has an extension other than .xz/.gz/.zst, e.g. .bz2 (bzip2), .lzma, an uncompressed .tar, or a name whose final extension via splitext is unexpected.

Common situations: An older or atypical build using bzip2, a minimal deb with an uncompressed data.tar, or a member name like data.tar.gz.xz where splitext returns .xz (fine) vs data.tar.bz2 where it returns .bz2 (unsupported).

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/36e0532410810b69. Report an issue: GitHub.

Appendix: source

Thrown at eng/common/cross/install-debs.py:332

            subprocess.run([ar_tool, "p", os.path.abspath(deb_file), tar_filename], check=True, stdout=outfile, stderr=subprocess.PIPE)

        file_extension = os.path.splitext(tar_file_path)[1].lower()

        if file_extension == ".xz":
            mode = "r:xz"
        elif file_extension == ".gz":
            mode = "r:gz"
        elif file_extension == ".zst":
            # zstd is not supported by standard library yet
            decompressed_tar_path = tar_file_path.replace(".zst", "")
            with open(tar_file_path, "rb") as zst_file, open(decompressed_tar_path, "wb") as decompressed_file:
                dctx = zstandard.ZstdDecompressor()
                dctx.copy_stream(zst_file, decompressed_file)

            tar_file_path = decompressed_tar_path
            mode = "r"
        else:
            raise ValueError(f"Unsupported compression format: {file_extension}")

        with tarfile.open(tar_file_path, mode) as tar:
            tar.extractall(path=extract_dir, filter=_rootfs_extraction_filter)

def _rootfs_extraction_filter(member, dest_path):
    """Tarfile extraction filter based on the 'data' filter that additionally
    rewrites absolute-target symlinks/hardlinks into rootfs-relative paths.
    """
    if (member.issym() or member.islnk()) and os.path.isabs(member.linkname):
        link_dir = os.path.dirname(member.name)
        new_linkname = os.path.relpath(member.linkname.lstrip('/'),
                                       start=link_dir or '.')
        member = member.replace(linkname=new_linkname, deep=False)
    return tarfile.data_filter(member, dest_path)

def finalize_setup(rootfsdir):
    lib_dir = os.path.join(rootfsdir, 'lib')
    usr_lib_dir = os.path.join(rootfsdir, 'usr', 'lib')

View on GitHub (pinned to 3a2006ef56)