dotnet/aspnetcore · error · FileNotFoundError

Could not find 'data.tar.*' in

Error message

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

What it means

Raised as FileNotFoundError by extract_deb_file when `ar t <deb>` lists no member whose name starts with 'data.tar'. Every conformant .deb archive contains data.tar.<comp>; the throw means the file is not a .deb, is corrupt, or is a different archive format.

Solutions

  1. Inspect the file: `file path/to/foo.deb` and `ar t path/to/foo.deb` — if it is HTML or empty, the download itself was wrong (see errors 345/346/347).
  2. Re-run with a different --mirror to rule out a mirror serving an error page with HTTP 200.
  3. Confirm the --artool exists and is a real GNU/BSD ar (run `ar --version` or `llvm-ar --version`).
  4. Verify disk space in the tmp_dir; a partial write leaves a truncated archive that lists no members.

Example fix

# before
python3 install-debs.py --artool llvm-ar --mirror http://bad-mirror ... 
# 'Could not find data.tar.* in rootfs/cache/libc6.deb' (mirror served HTML)

# after
curl -I http://bad-mirror/.../libc6_1.0_amd64.deb   # discover it returns HTML
python3 install-debs.py --artool ar --mirror http://deb.debian.org/debian ...
Defensive patterns

Strategy: validation

Validate before calling

# After download, before extraction, assert each .deb is a real ar archive with data.tar:
for f in tmp/*.deb; do
  ar t "$f" 2>/dev/null | grep -q '^data\.tar' || { echo "not a valid deb: $f"; file "$f"; exit 1; }
done

Type guard

import os, subprocess
def deb_has_data_tar(path: str) -> bool:
    if not os.path.isfile(path) or os.path.getsize(path) < 100: return False
    r = subprocess.run(['ar', 't', path], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
    return any(line.startswith('data.tar') for line in r.stdout.decode().splitlines())

Prevention

When it happens

Trigger: subprocess.run([ar_tool, 't', deb_file]) succeeds (check=True) but none of the stdout lines starts with 'data.tar', so tar_filename stays None and the raise fires.

Common situations: Downloaded file is actually an HTML error page saved with a .deb extension (mirror 404 page returned 200 with HTML); download was truncated so the ar archive is incomplete; wrong --artool (e.g. llvm-ar in a mode that lists differently); file is a .udeb or .ddeb with a different member layout; disk full mid-download so the file is partial.

Related errors


AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11). Data as JSON: /api/errors/fb67956123cf30eb. Report an issue: GitHub.

Appendix: source

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

    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([ar_tool, "t", os.path.abspath(deb_file)], cwd=tmp_subdir, check=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}..")

        with open(tar_file_path, "wb") as outfile:
            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()

View on GitHub (pinned to 3600ca084e)