wasmerio/wasmer · error

could not decode gz: {e1}, could not decode xz: {e2}

Error message

could not decode gz: {e1}, could not decode xz: {e2}

What it means

In try_unpack_targz, the archive may actually be a raw gzip or xz stream rather than a plain tar. The function tries gz decoding, then xz decoding; if both fail, it merges both underlying errors into this combined message so the caller can see why each decoder rejected the input. It means the file at target_targz_path is neither valid gzip nor valid xz data.

Source

Thrown at lib/cli/src/utils/unpack.rs:79

            unpack_sans_parent(ar, target_path).map_err(|e| {
                anyhow::anyhow!(
                    "failed to unpack (sans parent) {}: {e}",
                    target_targz_path.display()
                )
            })
        } else {
            ar.unpack(target_path).map_err(|e| {
                anyhow::anyhow!(
                    "failed to unpack (with parent) {}: {e}",
                    target_targz_path.display()
                )
            })
        }
    };

    try_decode_gz().or_else(|e1| {
        try_decode_xz()
            .map_err(|e2| anyhow::anyhow!("could not decode gz: {e1}, could not decode xz: {e2}"))
    })?;

    Ok(Path::new(&target_targz_path).to_path_buf())
}

pub fn unpack_with_parent<R>(mut archive: tar::Archive<R>, dst: &Path) -> Result<(), anyhow::Error>
where
    R: std::io::Read,
{
    use std::path::Component::Normal;

    let dst_normalized = normalize_path(dst.to_string_lossy().as_ref());

    for entry in archive.entries()? {
        let mut entry = entry?;
        let path: PathBuf = entry
            .path()?
            .components()

View on GitHub (pinned to 8c4b9ee9d3)

Solutions

  1. Inspect the file: `file <path>` / `head -c 200 <path>` — if it's HTML or text, the download URL or auth token is wrong, not the decompressor.
  2. Re-download the artifact; compare checksums/size with the published release.
  3. Check the server actually serves gzip or xz; if it's zstd or another format, upgrade the CLI or decompress manually before unpacking.
  4. If behind a proxy, verify the proxy isn't rewriting/erroring on the response body.
  5. Read both `{e1}` and `{e2}` inner errors: identical 'unexpected EOF' means truncation; 'invalid magic' means wrong format.

Example fix

// before: blindly unpacking whatever was downloaded
let path = try_unpack_targz(&cached, &dest, false).await?;
// after: sanity-check the format first
let bytes = std::fs::read(&cached)?;
let gz = bytes.starts_with(&[0x1f, 0x8b]);
let xz = bytes.starts_with(&[0xfd, b'7', b'z', b'X', b'Z', 0x00]);
anyhow::ensure!(gz || xz, "downloaded artifact is not gz/xz: starts with {:?}", &bytes[..8.min(bytes.len())]);
let path = try_unpack_targz(&cached, &dest, false).await?;
Defensive patterns

Strategy: validation

Validate before calling

// check magic bytes before attempting gz/xz decode
fn looks_like_archive(bytes: &[u8]) -> bool {
    bytes.starts_with(&[0x1f, 0x8b]) // gzip
        || bytes.starts_with(&[0xfd, b'7', b'z', b'X', b'Z', 0x00]) // xz
}

Type guard

fn is_gzip(b: &[u8]) -> bool { b.len() >= 2 && b[0] == 0x1f && b[1] == 0x8b }
fn is_xz(b: &[u8]) -> bool { b.starts_with(b"\xfd7zXZ\x00") }

Try / catch

match try_unpack_targz(&path, &dest, false) {
    Ok(p) => p,
    Err(e) if e.to_string().starts_with("could not decode gz") => {
        anyhow::bail!("downloaded file is not gz/xz — check URL/auth, got: {}", first_bytes(&path));
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: try_decode_gz() fails and try_decode_xz() also fails — e.g. the downloaded file is an HTML error page, a plain (uncompressed) tar, zstd-compressed, or a truncated/partial download.

Common situations: A proxy or CDN returned an HTML 403/404 page saved with the archive's filename; the registry serves a new compression format the installed CLI doesn't understand; download interrupted mid-stream.

Related errors


AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01). Data as JSON: /api/errors/d7f26886488785e4. Report an issue: GitHub.