denoland/deno · error · TypeError
Invalid WebAssembly content type
Error message
Invalid WebAssembly content type
What it means
WebAssembly.compileStreaming/instantiateStreaming in Deno validate the response Content-Type: it must equal 'application/wasm' after lowercasing, otherwise the compiler would be fed bytes of unknown type. The check is skipped for file:// URLs because file fetches carry no Content-Type. Note the comparison is exact, so parameters such as 'application/wasm; charset=utf-8' are rejected too.
Source
Thrown at ext/fetch/26_fetch.js:1027
try {
const res = webidl.converters["Response"](
source,
"Failed to execute 'WebAssembly.compileStreaming'",
"Argument 1",
);
// 2.3.
// The spec is ambiguous here, see
// https://github.com/WebAssembly/spec/issues/1138. The WPT tests expect
// the raw value of the Content-Type attribute lowercased. We ignore this
// for file:// because file fetches don't have a Content-Type.
if (!StringPrototypeStartsWith(res.url, "file://")) {
const contentType = res.headers.get("Content-Type");
if (
typeof contentType !== "string" ||
StringPrototypeToLowerCase(contentType) !== "application/wasm"
) {
throw new TypeError("Invalid WebAssembly content type");
}
}
// 2.5.
if (!res.ok) {
throw new TypeError(
`Failed to receive WebAssembly content: HTTP status code ${res.status}`,
);
}
// Pass the resolved URL to v8.
op_wasm_streaming_set_url(rid, res.url);
if (res.body !== null) {
// 2.6.
// Rather than consuming the body as an ArrayBuffer, this feeds each chunk
// to the streaming compiler as soon as it's available. Instead of reading
// the body chunk-by-chunk in JS and calling `op_wasm_streaming_feed` onceView on GitHub (pinned to 89f33cbef2)
Solutions
- Serve the module with exactly 'Content-Type: application/wasm' and no parameters
- Fall back to non-streaming compilation: WebAssembly.instantiate(await res.arrayBuffer(), imports)
- If you cannot change headers, fetch the bytes first, verify manually, then compile from the buffer
Example fix
// before
const { instance } = await WebAssembly.instantiateStreaming(fetch("/lib.wasm")); // Invalid WebAssembly content type
// after (option 1: fix server header to application/wasm)
// after (option 2: compile from buffer)
const res = await fetch("/lib.wasm");
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { instance } = await WebAssembly.instantiate(await res.arrayBuffer()); Defensive patterns
Strategy: fallback
Validate before calling
function isWasmResponseType(res) {
const ct = res.headers.get("content-type");
return typeof ct === "string" && ct.toLowerCase().split(";")[0].trim() === "application/wasm";
} Type guard
function canStreamCompile(res: Response): boolean {
const ct = res.headers.get("content-type");
return res.ok && ct !== null && ct.toLowerCase().startsWith("application/wasm");
} Try / catch
async function instantiateAnyhow(url, imports) {
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
try {
return await WebAssembly.instantiateStreaming(Promise.resolve(res), imports);
} catch (err) {
if (err instanceof TypeError && err.message === "Invalid WebAssembly content type") {
return await WebAssembly.instantiate(await res.arrayBuffer(), imports); // non-streaming fallback
}
throw err;
}
} Prevention
- Serve .wasm with exactly 'application/wasm' (no charset parameters) and verify with curl -I
- Validate the content-type header yourself before choosing the streaming API
- Keep a buffer-based compile path for servers you do not control
- Remember file:// URLs skip the check but servers do not
When it happens
Trigger: A server responding with Content-Type: text/plain, application/octet-stream, no Content-Type header, or application/wasm with appended parameters (charset) when the wasm module is fetched for instantiateStreaming; happens for http(s) URLs but not file://.
Common situations: Static file servers that guess MIME types and mark .wasm as application/octet-stream; dev servers without a wasm MIME mapping; CDNs/frameworks that append charset to every text-ish response; proxy layers stripping headers.
Related errors
- Failed to receive WebAssembly content: HTTP status code ${re
- Body can not be decoded as form data
- Missing content type
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/fa704bd53dabe5db.
Report an issue: GitHub.