{"record":{"id":"d7f26886488785e4","repo":"wasmerio/wasmer","slug":"could-not-decode-gz-e1-could-not-decode-xz-e","errorCode":null,"errorMessage":"could not decode gz: {e1}, could not decode xz: {e2}","messagePattern":"could not decode gz: (.+?), could not decode xz: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/cli/src/utils/unpack.rs","lineNumber":79,"sourceCode":"            unpack_sans_parent(ar, target_path).map_err(|e| {\n                anyhow::anyhow!(\n                    \"failed to unpack (sans parent) {}: {e}\",\n                    target_targz_path.display()\n                )\n            })\n        } else {\n            ar.unpack(target_path).map_err(|e| {\n                anyhow::anyhow!(\n                    \"failed to unpack (with parent) {}: {e}\",\n                    target_targz_path.display()\n                )\n            })\n        }\n    };\n\n    try_decode_gz().or_else(|e1| {\n        try_decode_xz()\n            .map_err(|e2| anyhow::anyhow!(\"could not decode gz: {e1}, could not decode xz: {e2}\"))\n    })?;\n\n    Ok(Path::new(&target_targz_path).to_path_buf())\n}\n\npub fn unpack_with_parent<R>(mut archive: tar::Archive<R>, dst: &Path) -> Result<(), anyhow::Error>\nwhere\n    R: std::io::Read,\n{\n    use std::path::Component::Normal;\n\n    let dst_normalized = normalize_path(dst.to_string_lossy().as_ref());\n\n    for entry in archive.entries()? {\n        let mut entry = entry?;\n        let path: PathBuf = entry\n            .path()?\n            .components()","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/wasmerio/wasmer/blob/8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5/lib/cli/src/utils/unpack.rs#L61-L97","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Re-download the artifact; compare checksums/size with the published release.","Check the server actually serves gzip or xz; if it's zstd or another format, upgrade the CLI or decompress manually before unpacking.","If behind a proxy, verify the proxy isn't rewriting/erroring on the response body.","Read both `{e1}` and `{e2}` inner errors: identical 'unexpected EOF' means truncation; 'invalid magic' means wrong format."],"exampleFix":"// before: blindly unpacking whatever was downloaded\nlet path = try_unpack_targz(&cached, &dest, false).await?;\n// after: sanity-check the format first\nlet bytes = std::fs::read(&cached)?;\nlet gz = bytes.starts_with(&[0x1f, 0x8b]);\nlet xz = bytes.starts_with(&[0xfd, b'7', b'z', b'X', b'Z', 0x00]);\nanyhow::ensure!(gz || xz, \"downloaded artifact is not gz/xz: starts with {:?}\", &bytes[..8.min(bytes.len())]);\nlet path = try_unpack_targz(&cached, &dest, false).await?;","handlingStrategy":"validation","validationCode":"// check magic bytes before attempting gz/xz decode\nfn looks_like_archive(bytes: &[u8]) -> bool {\n    bytes.starts_with(&[0x1f, 0x8b]) // gzip\n        || bytes.starts_with(&[0xfd, b'7', b'z', b'X', b'Z', 0x00]) // xz\n}","typeGuard":"fn is_gzip(b: &[u8]) -> bool { b.len() >= 2 && b[0] == 0x1f && b[1] == 0x8b }\nfn is_xz(b: &[u8]) -> bool { b.starts_with(b\"\\xfd7zXZ\\x00\") }","tryCatchPattern":"match try_unpack_targz(&path, &dest, false) {\n    Ok(p) => p,\n    Err(e) if e.to_string().starts_with(\"could not decode gz\") => {\n        anyhow::bail!(\"downloaded file is not gz/xz — check URL/auth, got: {}\", first_bytes(&path));\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Peek at the first bytes of any downloaded artifact before decompressing","Validate download URLs and auth tokens so servers don't return HTML error pages","Verify content-length / checksum after download to catch truncation","Keep the CLI updated for newly supported compression formats"],"tags":["rust","compression","gzip","xz","download"],"backgroundTag":"unsupported-compression-format","analyzedSha":"8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5","analyzedAt":"2026-09-01T23:06:31.009Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}