rust-lang/rust · error
tarball extension not recognized: {}
Error message
tarball extension not recognized: {} What it means
In src/tools/build-manifest/src/versions.rs the tarball reader only recognizes .gz (GzDecoder) and .xz (XzDecoder) extensions. Any other extension (or no extension) falls through to unimplemented!("tarball extension not recognized: {}") at versions.rs:255.
Source
Thrown at src/tools/build-manifest/src/versions.rs:255
}
fn load_version_from_tarball_inner(&mut self, tarball: &Path) -> Result<VersionInfo, Error> {
let file = match File::open(&tarball) {
Ok(file) => file,
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
// Missing tarballs do not return an error, but return empty data.
println!("warning: missing tarball {}", tarball.display());
return Ok(VersionInfo::default());
}
Err(err) => return Err(err.into()),
};
let mut tar: Archive<Box<dyn std::io::Read>> =
Archive::new(if tarball.extension().map_or(false, |e| e == "gz") {
Box::new(GzDecoder::new(file))
} else if tarball.extension().map_or(false, |e| e == "xz") {
Box::new(XzDecoder::new(file))
} else {
unimplemented!("tarball extension not recognized: {}", tarball.display())
});
let mut version = None;
let mut git_commit = None;
for entry in tar.entries()? {
let mut entry = entry?;
let dest;
match entry.path()?.components().nth(1).and_then(|c| c.as_os_str().to_str()) {
Some("version") => dest = &mut version,
Some("git-commit-hash") => dest = &mut git_commit,
_ => continue,
}
let mut buf = String::new();
entry.read_to_string(&mut buf)?;
*dest = Some(buf);
// Short circuit to avoid reading the whole tar file if not necessary.View on GitHub (pinned to 7088e4b63a)
Solutions
- Ensure the input tarball uses .tar.gz or .tar.xz compression.
- Recompress the artifact: e.g. 'zstd -d f.tar.zst && gzip f.tar' to produce a .gz build-manifest can read.
- Extend build-manifest to add a zstd/bzip2 branch if your release now ships those formats.
- Check for a missing/empty extension (e.g. a directory passed instead of a tarball).
Example fix
// before
let tar = Archive::new(/* extension is .zst -> panic */);
// after: add zstd support
use zstd::Decoder;
let decoder = if ext == "zst" { Box::new(Decoder::new(file)?) } else { /* gz/xz */ }; Defensive patterns
Strategy: validation
Validate before calling
fn is_supported_tarball(path: &Path) -> bool {
matches!(path.extension().and_then(|e| e.to_str()), Some("gz") | Some("xz"))
}
// Only pass tarballs where is_supported_tarball returns true to the version reader. Prevention
- Keep release tarballs as .tar.gz or .tar.xz for build-manifest.
- Recompress .zst/.bz2 artifacts before invoking build-manifest.
- Extend the extension match when you change the release compression.
When it happens
Trigger: Running build-manifest to extract version/git-commit files from a release tarball whose name does not end in .tar.gz or .tar.xz — e.g. a .tar.zst, .tar.bz2, a plain .tar, or a misnamed file.
Common situations: Release pipeline producing .zst tarballs; a manually renamed artifact; a dist that changed compression format without updating build-manifest.
Related errors
- couldn't figure out the format of {}
- invalid compression profile: {other}
- unknown compression format: {}
AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10).
Data as JSON: /api/errors/1675ba0adbaa9a11.
Report an issue: GitHub.