denoland/deno · error · AnyError
Unsupported archive type: '{ext}'
Error message
Unsupported archive type: '{ext}' What it means
`unpack_into_dir` dispatches solely on the extension of `archive_name` and implements only the `zip` arm; every other extension is rejected before any bytes are read. Because Deno's own release artifacts are zips, end users should rarely see this — it usually means a custom feed or API caller supplied a tar/tar.gz/7z artifact where a zip was expected.
Source
Thrown at cli/util/archive.rs:112
let archive_ext = Path::new(archive_name)
.extension()
.and_then(|ext| ext.to_str())
.unwrap();
match archive_ext {
"zip" => match unzip(archive_name, archive_data, dest_path) {
Ok(()) if !exe_path.exists() => {
log::warn!("unpacking via the zip crate didn't produce the executable");
// No error but didn't produce exe, fallback to shelling out
unzip_with_shell(&archive_path, archive_data, dest_path)?;
}
Ok(_) => {}
Err(e) => {
log::warn!("unpacking via zip crate failed: {e}");
// Fallback to shelling out
unzip_with_shell(&archive_path, archive_data, dest_path)?;
}
},
ext => bail!("Unsupported archive type: '{ext}'"),
}
assert!(exe_path.exists());
Ok(exe_path)
}
#[cfg(test)]
mod tests {
use std::io::Write;
use super::*;
fn make_zip(file_name: &str, contents: &[u8]) -> Vec<u8> {
let mut buf = Vec::new();
let mut writer = zip::ZipWriter::new(std::io::Cursor::new(&mut buf));
writer
.start_file(file_name, zip::write::SimpleFileOptions::default())
.unwrap();View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Re-package or fetch the artifact as a .zip (Deno publishes zips for its binaries).
- If scripting against the API, assert the extension is `zip` before calling `unpack_into_dir`.
- If a zip was expected, inspect the actual download URL/response — a proxy or redirect may be serving something else under a different filename.
Example fix
// before
let exe = unpack_into_dir(UnpackArgs { archive_name: "deno.tar.gz", ..args })?;
// after: only the zip arm exists
let exe = unpack_into_dir(UnpackArgs { archive_name: "deno.zip", ..args })?; Defensive patterns
Strategy: validation
Validate before calling
// reject unsupported archives before calling unpack_into_dir
let ext = std::path::Path::new(archive_name)
.extension()
.and_then(|e| e.to_str());
if ext != Some("zip") {
return Err(anyhow::anyhow!("only .zip archives are supported"));
} Prevention
- Assert the artifact extension is zip before invoking download/unpack helpers.
- Serve and consume release artifacts in one canonical format (zip).
- Log the served Content-Disposition/filename when behind proxies so format mismatches are visible.
When it happens
Trigger: Calling `unpack_into_dir` (directly, or via Deno install/upgrade machinery pointed at a custom source) with an `archive_name` whose extension is not exactly `zip` — e.g. `deno.tar.gz`, `deno.tgz`, or an artifact whose filename lost its extension.
Common situations: Custom upgrade feeds or mirrors serving .tar.gz instead of .zip; test fixtures with misnamed archives; a download URL that redirects to an error page whose 'filename' has a different extension.
Related errors
- Failed to unpack archive.
- unsupported archive format: {name}
- refusing to add {} to tarball: {}
- tar entry '{}' has invalid offset/size (offset={}, size={})
- refusing zip entry with unsafe path: {}
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/cb709cd22769f1b5.
Report an issue: GitHub.