{"record":{"id":"fb67956123cf30eb","repo":"dotnet/aspnetcore","slug":"could-not-find-data-tar-in-deb-file","errorCode":null,"errorMessage":"Could not find 'data.tar.*' in {deb_file}.","messagePattern":"Could not find 'data\\.tar\\.\\*' in (.+?)\\.","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"eng/common/cross/install-debs.py","lineNumber":308,"sourceCode":"\n    print(\"All done!\")\n\ndef extract_deb_file(deb_file, tmp_dir, extract_dir, ar_tool):\n    \"\"\"Extract .deb file contents\"\"\"\n\n    os.makedirs(extract_dir, exist_ok=True)\n\n    with tempfile.TemporaryDirectory(dir=tmp_dir) as tmp_subdir:\n        result = subprocess.run([ar_tool, \"t\", os.path.abspath(deb_file)], cwd=tmp_subdir, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n\n        tar_filename = None\n        for line in result.stdout.decode().splitlines():\n            if line.startswith(\"data.tar\"):\n                tar_filename = line.strip()\n                break\n\n        if not tar_filename:\n            raise FileNotFoundError(f\"Could not find 'data.tar.*' in {deb_file}.\")\n\n        tar_file_path = os.path.join(tmp_subdir, tar_filename)\n        print(f\"Extracting {tar_filename} from {deb_file}..\")\n\n        with open(tar_file_path, \"wb\") as outfile:\n            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()","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/eng/common/cross/install-debs.py#L290-L326","documentation":"extract_deb_file runs 'ar t <deb>' to list the archive members and looks for one starting with 'data.tar'. If none is found, it raises FileNotFoundError. A well-formed .deb always contains control.tar.* and data.tar.*; a missing data.tar means the .deb is truncated, corrupt, or not actually a .deb (e.g., an HTML error page saved with a .deb name).","triggerScenarios":"Reached during install_packages after the parallel download. For each resolved package, 'ar t' is run on the downloaded file; the stdout is scanned line-by-line for a 'data.tar' prefix. A 404 HTML page or partial download saved to the .deb path produces no matching line and raises.","commonSituations":"download_file wrote a non-200 response body to disk (note: download_file raises on non-200, but a transparent proxy could still serve a 200 with an error body); the .deb was truncated by a network interruption that did not trigger a ClientError; the ar tool is misconfigured (e.g., llvm-ar behaving differently) and produces unexpected output; the file was overwritten by a concurrent download.","solutions":["Inspect the offending .deb file with 'file <deb>' and 'ar t <deb>' — if it is HTML or empty, the download is the real problem.","Re-run with a clean mirror; transient corruption usually clears on re-download.","Ensure the --artool (default 'ar') is GNU binutils ar; llvm-ar may format member listings differently.","Delete the tmp_dir before re-running so stale partial files do not mask fresh downloads."],"exampleFix":"# before\npython3 install-debs.py --artool llvm-ar --mirror http://broken/ ...\n# Could not find 'data.tar.*' in /tmp/.../libc6.deb\n\n# diagnose\nfile /tmp/.../libc6.deb   # -> HTML document text\n\n# after\npython3 install-debs.py --mirror http://deb.debian.org/debian ...","handlingStrategy":"validation","validationCode":"# Validate the .deb structure before passing to extract_deb_file\nimport subprocess, os\ndef deb_has_data_tar(path: str, ar: str = 'ar') -> bool:\n    r = subprocess.run([ar, 't', os.path.abspath(path)], capture_output=True)\n    return any(line.startswith('data.tar') for line in r.stdout.decode().splitlines())\n\nif not deb_has_data_tar(deb_file):\n    raise SystemExit(f'{deb_file} is not a valid .deb (no data.tar); re-download')","typeGuard":null,"tryCatchPattern":"try:\n    extract_deb_file(deb_file, tmp_dir, extract_dir, ar_tool)\nexcept FileNotFoundError as e:\n    if 'data.tar' in str(e):\n        print(f'{deb_file} corrupt; deleting and skipping')\n        os.remove(deb_file)\n        continue\n    raise","preventionTips":["Run 'file <deb>' on downloaded .debs in CI to catch HTML/empty responses.","Ensure --artool is GNU binutils ar.","Delete tmp_dir before each build to avoid stale partial files.","Verify download_file raises on non-200 so error pages never reach disk."],"tags":["python","debian","deb","ar","filesystem","install-debs","rootfs"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}