tonhowtf/omniget · error · anyhow::Error
Failed to read tar entries
Error message
Failed to read tar entries: {} What it means
After opening the .tar.xz and wrapping it in an xz2 XzDecoder and tar::Archive, extract_tar_xz_ffmpeg calls archive.entries() to iterate members. Failure here means the tar iterator could not be created/started - typically the underlying stream is not a valid tar, or the xz stream is corrupt/truncated.
Solutions
- Delete and re-download the archive; verify integrity (size/checksum) before extraction
- Verify the file magic bytes: FD 37 7A 58 5A 00 for xz, and gzip's 1F 8B if the upstream switched formats
- Use the matching decoder (GzDecoder vs XzDecoder) for the actual format
- Check that the download response status was success and Content-Length matched
Example fix
// before
let decompressor = xz2::read::XzDecoder::new(file);
// after
let mut magic = [0u8; 6];
let mut peek = std::fs::File::open(&archive_path)?;
use std::io::Read;
peek.read_exact(&mut magic)?;
if &magic != b"\xfd7zXZ\x00" {
return Err(anyhow!("Downloaded artifact is not an xz archive; re-download or switch decoder"));
}
let decompressor = xz2::read::XzDecoder::new(peek); Defensive patterns
Strategy: validation
Validate before calling
let mut f = std::fs::File::open(&archive_path)?;
let mut magic = [0u8; 6];
std::io::Read::read_exact(&mut f, &mut magic)?;
if &magic != b"\xfd7zXZ\x00" {
return Err(anyhow!("artifact is not xz; check upstream format"));
} Type guard
fn is_xz_file(p: &std::path::Path) -> bool {
use std::io::Read;
std::fs::File::open(p).map(|mut f| {
let mut m = [0u8; 6];
f.read_exact(&mut m).is_ok() && &m == b"\xfd7zXZ\x00"
}).unwrap_or(false)
} Try / catch
match extract_tar_xz_ffmpeg(&path, &bin_dir, &ff, &fprobe).await {
Err(e) if e.to_string().contains("Failed to read tar entries") => {
// format mismatch or corruption: detect magic, re-download with correct decoder
std::fs::remove_file(&path).ok();
download_ffmpeg(...).await?;
},
r => r?,
} Prevention
- Check the xz magic bytes before choosing XzDecoder
- Track upstream FFmpeg release format changes (.tar.xz vs .tar.gz)
- Compare Content-Length with actual bytes downloaded
- Re-download rather than retry-extract on corruption
When it happens
Trigger: The downloaded file is not actually xz-compressed tar (e.g. gzip tar or plain HTML error page), the xz stream is truncated mid-download, or the tar header block is invalid.
Common situations: Upstream changed the artifact from .tar.xz to .tar.gz but the extractor was not updated; proxy returned an error page saved with a .tar.xz name; incomplete download on flaky network.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- tar.xz invalido
- Failed to read tar entry
- Failed to read entry path
- Failed to open aria2c zip
- tar.gz invalido
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/d33a3b1fc82f5391.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/dependencies.rs:634
bin_dir: &std::path::Path,
ffmpeg_name: &str,
ffprobe_name: &str,
) -> anyhow::Result<()> {
let archive_path = archive_path.to_path_buf();
let bin_dir = bin_dir.to_path_buf();
let ffmpeg_name = ffmpeg_name.to_string();
let ffprobe_name = ffprobe_name.to_string();
tokio::task::spawn_blocking(move || {
let file = std::fs::File::open(&archive_path)
.map_err(|e| anyhow!("Failed to open archive: {}", e))?;
let decompressor = xz2::read::XzDecoder::new(file);
let mut archive = tar::Archive::new(decompressor);
let targets = [ffmpeg_name.as_str(), ffprobe_name.as_str()];
for entry_result in archive
.entries()
.map_err(|e| anyhow!("Failed to read tar entries: {}", e))?
{
let mut entry = entry_result.map_err(|e| anyhow!("Failed to read tar entry: {}", e))?;
let path = entry
.path()
.map_err(|e| anyhow!("Failed to read entry path: {}", e))?;
let file_name = path.file_name().and_then(|n| n.to_str()).unwrap_or("");
for target in &targets {
if file_name == *target {
let dest = bin_dir.join(format!("{}.new", target));
let mut out = std::fs::File::create(&dest)?;
std::io::copy(&mut entry, &mut out)?;
break;
}
}
}
Ok::<(), anyhow::Error>(())
})
.awaitView on GitHub (pinned to 8600b91f42)