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

  1. Ensure the input tarball uses .tar.gz or .tar.xz compression.
  2. Recompress the artifact: e.g. 'zstd -d f.tar.zst && gzip f.tar' to produce a .gz build-manifest can read.
  3. Extend build-manifest to add a zstd/bzip2 branch if your release now ships those formats.
  4. 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

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


AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10). Data as JSON: /api/errors/1675ba0adbaa9a11. Report an issue: GitHub.