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
- 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
- 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)
- On the server/CDN, gate zstd on Accept-Encoding negotiation and exclude wasm clients that don't advertise zstd support
- 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
- Configure CDNs/proxies to negotiate encoding via Accept-Encoding rather than force-serving zstd
- Keep a plain (identity-encoded) mirror of package artifacts for wasm clients
- Don't wrap the platform fetch with a decoder-less raw-bytes fetch in browser builds
- Track zstd support in the loader for wasm32 and upgrade when it lands
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
- unsupported content-encoding: {other}
- Timeout while downloading response body
- Could not apply request header: '{name}': '{value}'
AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01).
Data as JSON: /api/errors/d0b66308fb74a99d.
Report an issue: GitHub.