dotnet/yarp · error · FileNotFoundError
Could not find 'data.tar.*' in {deb_file}.
Error message
Could not find 'data.tar.*' in {deb_file}. What it means
This FileNotFoundError is raised in extract_deb_file after running 'ar t <deb_file>' to list the archive's member files. The code scans stdout lines for one starting with 'data.tar' (the member that holds the actual package payload). If no such member is found, the .deb file does not contain a data.tar archive -- meaning it is not a valid Debian package, is corrupted, was truncated during download, or is actually a different file type (e.g. an HTML error page saved with a .deb extension).
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 bd11867bee)
Solutions
- Check the file type: run file <deb_file> to confirm it is actually a Debian binary package (should report 'Debian binary package').
- Inspect the file size -- if it is suspiciously small (a few KB), it is likely an error page, not a real package.
- Manually run: ar t <deb_file> to see what members are listed and confirm the ar tool works.
- Verify the download succeeded -- check for a SHA256 mismatch (error 102) that may have been logged but the file still written.
- Re-download the specific .deb file and verify its integrity before extraction.
- Ensure the correct ar tool is available: which ar (or specify --artool llvm-ar explicitly).
- Add a pre-extraction check: verify the file starts with the '!<arch>' magic bytes that identify ar archives.
Example fix
# before -- assumes data.tar always exists in the .deb
if not tar_filename:
raise FileNotFoundError(f"Could not find 'data.tar.*' in {deb_file}.")
# after -- verify the file is a valid .deb before attempting extraction
with open(deb_file, 'rb') as f:
magic = f.read(8)
if magic != b'!<arch>':
raise FileNotFoundError(
f"{deb_file} is not a valid Debian archive (bad magic: {magic!r}). "
f"The download may have saved an error page.")
if not tar_filename:
raise FileNotFoundError(f"Could not find 'data.tar.*' in {deb_file}.") Defensive patterns
Strategy: validation
Validate before calling
# Pre-check: verify the file is a valid ar archive before extraction.
import os
_DEB_MAGIC = b'!<arch>'
def is_valid_deb(path):
if not os.path.exists(path) or os.path.getsize(path) < 100:
return False
with open(path, 'rb') as f:
return f.read(8) == _DEB_MAGIC Type guard
# Check ar archive magic bytes
def is_ar_archive(path):
try:
with open(path, 'rb') as f:
return f.read(8) == b'!<arch>'
except (OSError, IOError):
return False Try / catch
# Wrap extraction and skip corrupt .deb files
try:
extract_deb_file(deb_file, tmp_dir, extract_dir, ar_tool)
except FileNotFoundError as e:
if 'data.tar' in str(e):
print(f"WARNING: {deb_file} has no data.tar member. File may be corrupt. Skipping.")
continue
raise Prevention
- Verify each .deb file's magic bytes ('!<arch>') before attempting extraction.
- Check file sizes after download -- a .deb that is only a few KB is likely an error page.
- Ensure downloads are validated (SHA256 check) before extraction so corrupt files are caught earlier.
- Verify the ar tool is installed and on PATH before running the batch extraction.
- Log the 'ar t' output for each .deb to diagnose which file is problematic.
When it happens
Trigger: extract_deb_file (lines 293-308) runs subprocess.run([ar_tool, 't', deb_file]) and iterates result.stdout lines looking for one starting with 'data.tar'. If none is found, tar_filename stays None and the exception fires. This occurs when: the downloaded .deb is an HTML error page (404/403 page saved as .deb) because the download status wasn't checked properly; the file was truncated; the file is a .udeb or other variant with a different internal structure; the ar_tool ('ar' or 'llvm-ar') failed silently or returned unexpected output format; the file is genuinely corrupt.
Common situations: A 404 or 403 response body was saved as a .deb file because the download path returned non-200 but the error wasn't propagated (related to error 103's retry bug); the .deb was partially downloaded (network interruption, disk full); the file is actually a .rpm, .tar, or HTML page mislabeled; the ar tool path is wrong or ar is not installed, causing 'ar t' to produce empty stdout (though check=True should catch non-zero exit); using llvm-ar which may output member names in a different format; the .deb uses a non-standard archive format.
Related errors
- Unsupported compression format: {file_extension}
- SHA256 mismatch for {url}: expected {checksum}, got {sha256}
- Failed to download {url}, Status Code: {response.status}
- Failed to download {url} after {max_retries} attempts.
- SHA256 mismatch for {path}: expected {packages_sha}, got {sh
AI-assisted analysis of dotnet/yarp@bd11867bee (2026-08-13).
Data as JSON: /api/errors/4d3e754141e8e688.
Report an issue: GitHub.