rust-lang/rust · error · anyhow::Error

couldn't figure out the format of {}

Error message

couldn't figure out the format of {}

What it means

Thrown by the rust-installer Combiner::run method when detecting the compression format of an input tarball. CompressionFormat::detect_from_path inspects the file extension and only recognizes .gz and .xz (compression.rs:54-59). Any other extension (or no extension) returns None, which becomes this anyhow error at combiner.rs:84.

Source

Thrown at src/tools/rust-installer/src/combiner.rs:84

impl Combiner {
    /// Combines the installer tarballs.
    pub fn run(self) -> Result<()> {
        create_dir_all(&self.work_dir)?;

        let package_dir = Path::new(&self.work_dir).join(&self.package_name);
        if package_dir.exists() {
            remove_dir_all(&package_dir)?;
        }
        create_dir_all(&package_dir)?;

        // Merge each installer into the work directory of the new installer.
        let components = create_new_file(package_dir.join("components"))?;
        for input_tarball in self.input_tarballs.split(',').map(str::trim).filter(|s| !s.is_empty())
        {
            // Extract the input tarballs
            let compression =
                CompressionFormat::detect_from_path(input_tarball).ok_or_else(|| {
                    anyhow::anyhow!("couldn't figure out the format of {}", input_tarball)
                })?;
            Archive::new(compression.decode(input_tarball)?).unpack(&self.work_dir).with_context(
                || format!("unable to extract '{}' into '{}'", &input_tarball, self.work_dir),
            )?;

            let pkg_name =
                input_tarball.trim_end_matches(&format!(".tar.{}", compression.extension()));
            let pkg_name = Path::new(pkg_name).file_name().unwrap();
            let pkg_dir = Path::new(&self.work_dir).join(pkg_name);

            // Verify the version number.
            let mut version = String::new();
            open_file(pkg_dir.join("rust-installer-version"))
                .and_then(|mut file| Ok(file.read_to_string(&mut version)?))
                .with_context(|| format!("failed to read version in '{}'", input_tarball))?;
            if version.trim().parse() != Ok(crate::RUST_INSTALLER_VERSION) {
                bail!("incorrect installer version in {}", input_tarball);
            }

View on GitHub (pinned to 7088e4b63a)

Solutions

  1. Re-compress the input tarball using gzip (producing .tar.gz) or xz (producing .tar.xz) — these are the only supported formats.
  2. Verify the file extension exactly matches .gz or .xz; check for typos like .xz vs .xs, or a missing dot.
  3. If you need bz2/zst support, extend CompressionFormat::detect_from_path in compression.rs to recognize the new extension and add a matching decoder.

Example fix

# before
# recompress a bz2 tarball to xz
tar xf package.tar.bz2 && tar cf - -C workdir package | xz -T6 > package.tar.xz
# then pass the .tar.xz to --input-tarballs
# after: --input-tarballs package.tar.xz
Defensive patterns

Strategy: validation

Validate before calling

// Before passing a tarball path to the Combiner, verify its extension.
use std::path::Path;

fn validate_tarball_extension(path: &str) -> Result<(), String> {
    let p = Path::new(path);
    let ext = p.extension().and_then(|e| e.to_str()).unwrap_or("");
    match ext {
        "gz" | "xz" => Ok(()),
        other => Err(format!("unsupported tarball extension '.{}': only .gz and .xz are supported", other)),
    }
}

Try / catch

// The Combiner returns anyhow::Result via Combiner::run().
match combiner.run() {
    Ok(()) => println!("installer created"),
    Err(e) => {
        if e.to_string().contains("couldn't figure out the format") {
            eprintln!("Input tarball has an unsupported compression. Use .tar.gz or .tar.xz.");
        }
        return Err(e);
    }
}

Prevention

When it happens

Trigger: Passing --input-tarballs with a file whose extension is not .gz or .xz (e.g., package.tar.bz2, package.tar.zst, package.tar with no compression suffix, or a typo like package.tar.x). The Combiner splits the --input-tarballs value by comma and calls detect_from_path on each.

Common situations: Building Rust installers manually with rust-installer and pointing to a tarball compressed with an unsupported algorithm; switching tarball compression from gz/xz to zstd without updating the installer toolchain; typo in the file extension.

Related errors


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