dotnet/maui · error · FileNotFoundError

Could not find 'data.tar.*' in {deb_file}.

Error message

Could not find 'data.tar.*' in {deb_file}.

What it means

extract_debs raises FileNotFoundError when `ar t` lists the archive contents and no entry starts with 'data.tar'. Every well-formed .deb must contain a data.tar.* member; its absence means the file is corrupt, truncated, or not actually a .deb (e.g. an HTML error page saved with a .deb extension).

Source

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

    print("All done!")

def extract_deb_file(deb_file, tmp_dir, extract_dir, ar_tool):
    """Extract .deb file contents"""

    os.makedirs(extract_dir, exist_ok=True)

    with tempfile.TemporaryDirectory(dir=tmp_dir) as tmp_subdir:
        result = subprocess.run(f"{ar_tool} t {os.path.abspath(deb_file)}", cwd=tmp_subdir, check=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        tar_filename = None
        for line in result.stdout.decode().splitlines():
            if line.startswith("data.tar"):
                tar_filename = line.strip()
                break

        if not tar_filename:
            raise FileNotFoundError(f"Could not find 'data.tar.*' in {deb_file}.")

        tar_file_path = os.path.join(tmp_subdir, tar_filename)
        print(f"Extracting {tar_filename} from {deb_file}..")

        subprocess.run(f"{ar_tool} p {os.path.abspath(deb_file)} {tar_filename} > {tar_file_path}", check=True, shell=True)

        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)

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Verify the file with `ar t file.deb` and confirm a data.tar.* entry exists; re-download if missing.
  2. Check the mirror URL and --suite; a wrong suite often yields a 404 body saved as the deb.
  3. Ensure --artool points to a real BSD/GNU ar (default 'ar'); llvm-ar output format can differ.
  4. Validate HTTP status of the deb download before extraction.

Example fix

# before
# silently corrupted file at debs/foo.deb
extract_debs(["debs/foo.deb"], ...)

# after
import subprocess
out = subprocess.run(["ar", "t", "debs/foo.deb"], capture_output=True, text=True).stdout
if not any(l.startswith("data.tar") for l in out.splitlines()):
    raise SystemExit("foo.deb is not a valid deb; re-download")
extract_debs(["debs/foo.deb"], ...)
Defensive patterns

Strategy: validation

Validate before calling

import subprocess
out = subprocess.run([ar_tool, 't', deb_file], capture_output=True, text=True).stdout
if not any(l.startswith('data.tar') for l in out.splitlines()):
    raise FileNotFoundError(f"Not a valid deb: {deb_file}")

Type guard

def is_valid_deb(deb_file, ar_tool='ar'):
    import subprocess
    out = subprocess.run([ar_tool,'t',deb_file],capture_output=True,text=True).stdout
    return any(l.startswith('data.tar') for l in out.splitlines())

Try / catch

try:
    extract_debs([deb], ...)
except FileNotFoundError:
    re_download(deb)

Prevention

When it happens

Trigger: Pointing install-debs.py at a file that is not a valid .deb, a partially downloaded .deb, or one whose data member is named differently than the data.tar prefix the script expects.

Common situations: A broken mirror/proxy returning an HTML 404 saved as the .deb, a download interrupted leaving a truncated file, or an ar tool mismatch producing unexpected output.

Related errors


AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13). Data as JSON: /api/errors/1f79e63a9c2e5cdb. Report an issue: GitHub.