wasmerio/wasmer · error

zstd content-encoding is not supported on wasm32

Error message

zstd content-encoding is not supported on wasm32

What it means

builtin_loader's decode_response_body handles Content-Encoding on downloaded package responses. On the wasm32 target (browser/JS runtime) the zstd decompression path is compiled out, so a response encoded with 'zstd' cannot be decoded and the loader bails. In browsers fetch would normally strip the encoding, so hitting this means the response arrived zstd-encoded outside a decoding layer.

Source

Thrown at lib/wasix/src/runtime/package_loader/builtin_loader.rs:394

        let mut reader: Box<dyn Read> = Box::new(std::io::Cursor::new(body));
        for encoding in encodings.iter().rev() {
            match encoding.as_str() {
                "gzip" => {
                    reader = Box::new(flate2::read::GzDecoder::new(reader));
                }
                "zstd" => {
                    #[cfg(not(target_arch = "wasm32"))]
                    {
                        reader = Box::new(
                            zstd::stream::read::Decoder::new(reader)
                                .context("failed to initialize zstd decoder")?,
                        );
                    }
                    #[cfg(target_arch = "wasm32")]
                    {
                        // NOTE: in browsers this code will not be hit because
                        // the fetch API automatically handles content decoding.
                        bail!("zstd content-encoding is not supported on wasm32");
                    }
                }
                "identity" => {}
                other => bail!("unsupported content-encoding: {other}"),
            }
        }

        let mut decoded = Vec::new();
        reader
            .read_to_end(&mut decoded)
            .context("failed to decode response body")?;
        Ok(decoded)
    }
}

impl Default for BuiltinPackageLoader {
    fn default() -> Self {
        BuiltinPackageLoader::new()

View on GitHub (pinned to 8c4b9ee9d3)

Solutions

  1. Reconfigure the serving side to not send Content-Encoding: zstd to wasm clients — serve identity encoding or compress with gzip/brotli that the wasm runtime supports
  2. Fix the fetch layer so content decoding happens transparently (browser fetch decompresses automatically; ensure you're using the platform fetch, not a wrapper that exposes raw bytes)
  3. On the server/CDN, gate zstd on Accept-Encoding negotiation and exclude wasm clients that don't advertise zstd support
  4. If you control the loader build, enable a zstd decoder crate behind the wasm32 cfg and handle the encoding instead of bailing

Example fix

// before: nginx serving zstd to all clients
// zstd on;  # applies Content-Encoding: zstd unconditionally
// after: only to clients that accept it (wasm loader doesn't)
zstd on;
zstd_accept_encoding "gzip"; // or serve identity to non-zstd UAs
// or client-side: fetch the uncompressed variant
let url = format!("{prefix}/{pkg}?encoding=identity");
Defensive patterns

Strategy: fallback

Validate before calling

// client-side pre-check: probe response headers before decoding the body
let resp = fetch_head(url).await?;
let enc = resp.headers().get("content-encoding").unwrap_or("identity");
if enc.eq_ignore_ascii_case("zstd") && is_wasm32() {
    // request an uncompressed variant instead
    url = format!("{url}?encoding=identity");
}

Type guard

fn is_decodable_on_wasm32(encoding: &str) -> bool {
    matches!(
        encoding.to_ascii_lowercase().as_str(),
        "identity" | "gzip" | "x-gzip" | "deflate" | "br"
    ) // zstd excluded on wasm32
}

Try / catch

match loader.download_and_decode(url).await {
    Ok(pkg) => use_package(pkg),
    Err(e) if e.to_string().contains("zstd content-encoding is not supported on wasm32") => {
        // fall back to a mirror/URL that serves identity encoding
        let alt = format!("{url}?encoding=identity");
        use_package(loader.download_and_decode(&alt).await?)
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Downloading a WASI package whose server responds with Content-Encoding: zstd while compiled to wasm32 (non-browser wasm runtime, or a browser context where the fetch API did not transparently decode, e.g. manual Request with cache/duck-typed fetch).

Common situations: Serving pre-compressed .zst assets from a CDN/proxy that sets Content-Encoding: zstd; custom registry/mirror that unconditionally zstd-compresses; running the loader in a worker or non-browser wasm embedder without zstd support.

Related errors


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