itch.io HTML5 Godot 4.5 WASM MIME application/octet-stream Boot Hang - Fix
Problem: You upload a Godot 4.5 HTML5 export to itch.io, open the browser demo, and the loader stalls on the progress bar—sometimes past 90%—without reaching the main scene. DevTools shows instantiateStreaming failed or Incorrect response MIME type for your .wasm file.
Who is affected now: Jam and festival teams pushing May–October 2026 itch HTML5 builds. itch’s CDN often serves unknown extensions as application/octet-stream, which blocks WebAssembly.instantiateStreaming in Chromium. The game worked in python -m http.server locally because your OS guessed MIME correctly—then fails only on itch.
Fastest safe fix: Confirm MIME with curl -I, re-upload a clean export folder, enable itch SharedArrayBuffer only when your export uses threads, and verify Content-Type: application/wasm in the Network panel before promoting the demo link.
Direct answer
A progress-bar hang with WASM MIME warnings means the browser refused to compile the module via streaming instantiation. Godot’s web loader expects application/wasm (or a correct gzip/br sibling chain). application/octet-stream is the generic bucket itch uses when the upload manifest does not declare WASM precisely—fix hosting/MIME first, then revisit thread and COOP settings.
Why this issue spikes in 2026
- Godot 4.5 tightened web export defaults and error surfacing around
instantiateStreaming. - 2026 jam seasons drive a wave of “upload zip → embed iframe” demos without a hosting smoke script.
- Teams copy threaded presets from the Godot web CI matrix guide but skip COOP/COEP on itch.
- Local tests mask MIME: desktop static servers often auto-map
.wasm; itch does not.
Pair with Godot SharedArrayBuffer / COOP / COEP hosting when threads are on, Godot 4.5 web audio silent first load when the game boots but audio is flat, and the Godot 4.5 web export audio MIME evening blog for a full hosting checklist.
Symptoms and search phrases
- Loader frozen at progress bar; no main scene.
- Console:
WebAssembly.instantiateStreamingfailed; expectedapplication/wasm. - Network tab:
.wasmresponse headerContent-Type: application/octet-stream. - Works on localhost, fails on itch embed and full-page tab.
- After enabling threads:
SharedArrayBuffer is not defined(different fix—see COOP help).
Root causes (check in order)
- itch MIME table serves
.wasmasapplication/octet-stream. - Wrong upload layout (nested folder, missing
index.htmlbeside.wasm). - Corrupt or mismatched gzip sibling (
.wasm.gzpresent but HTML points at raw.wasm). - Threaded export without itch SharedArrayBuffer toggle → isolation failure looks like hang.
- iframe embed on a parent page with conflicting COOP (rare on itch game page, common on external press kit).
Fastest safe fix path
Step 1 — Prove MIME with curl
Replace the URL with your itch game page’s WASM asset (from DevTools → Network → copy URL):
curl -sI "https://your-name.itch.io/your-game/html5/game.wasm" | findstr /i content-type
Pass: Content-Type: application/wasm
Fail: application/octet-stream or text/plain
On macOS/Linux use grep -i content-type instead of findstr.
Step 2 — Re-export with a known-good Web preset
In Godot 4.5 → Project → Export → Web:
| Preset lane | Threads | itch SharedArrayBuffer | When to use |
|---|---|---|---|
| Non-threaded | Off | Off | Fastest jam path; MIME-only failures |
| Threaded | On | On | Needs COOP/COEP + SAB; see COOP help |
- Export to an empty folder (
index.html,.wasm,.pck,.js). - Zip contents, not the parent folder name twice.
- Upload as HTML project on itch; run once in embedded and fullscreen modes.
Step 3 — Thread / COOP decision matrix
If Step 1 passes MIME but boot still hangs:
- Open console for
SharedArrayBuffer. - If present → enable itch SharedArrayBuffer for HTML5 games or re-export non-threaded preset.
- Follow COOP / COEP hosting fix for self-hosted mirrors; itch enables SAB via project checkbox, not custom headers.
Step 4 — Embed vs dedicated tab
- Open itch View game in new tab (top-level navigation).
- Repeat inside embed iframe on your press kit page if you use one.
- If tab works but embed fails → parent page isolation or third-party scripts block WASM; do not blame Godot export.
Step 5 — gzip / Brotli sibling hygiene
- If you ship only
.wasm, delete stale.wasm.gzfrom the upload folder. - If you ship compressed siblings, ensure
index.html/ Godot loader references the same file your server actually serves. - Re-upload after deleting orphans—itch CDN can cache wrong pairs for minutes.
Verification checklist
- [ ]
curl -sIshowsapplication/wasmfor the live.wasmURL - [ ] DevTools Network: 200 on
.wasm,.pck,.js; no 404 under nested path - [ ] Console: no
instantiateStreamingMIME errors - [ ] Progress bar reaches main scene in Chrome and Firefox
- [ ] Threaded builds: no
SharedArrayBuffererror when SAB toggle matches preset - [ ] Embedded + fullscreen itch modes both pass
CI prevention — wasm_mime_receipt_v1.json
Add a post-export smoke step before zipping:
{
"schema": "wasm_mime_receipt_v1",
"host": "itch.io",
"checked_at_utc": "2026-05-20T12:00:00Z",
"wasm_url": "https://example.itch.io/game/html5/game.wasm",
"content_type": "application/wasm",
"status_code": 200,
"instantiate_streaming_ok": true,
"pass": true
}
Wire curl -sI in CI after staging to a test itch page or mirror nginx with the same MIME table. See the Godot 4.5 web export resources list for MDN application/wasm references and export docs.
Alternative fixes
| Branch | When | Action |
|---|---|---|
| Self-hosted mirror | itch MIME cannot be influenced | Mirror build on nginx/Cloudflare with types { application/wasm wasm; } |
| Non-streaming fallback | Old Safari-only targets | Not recommended for 2026; fix MIME instead of disabling streaming globally |
| GDExtension web block | Instant crash after load | GDExtension web pruning preflight |
| Audio works, hang gone | Boot OK, silent audio | Web audio gesture unlock help |
Prevention
- Run MIME receipt CI on every HTML5 export artifact before updating the itch “Play in browser” link.
- Pin export preset name in
release-evidence/README(Web_nonthreaded_jamvsWeb_threaded). - Block marketing embeds until smoke test passes in both itch modes.
- Keep web CI matrix chapter presets as the single source of thread + header expectations.
FAQ
Does itch always serve octet-stream for WASM?
Not always—but it is common enough that you must curl the live URL after every upload, not assume.
Will renaming .wasm to .wasm.bin help?
No—Godot’s loader expects standard names from export. Fix MIME or host elsewhere.
Is this the same as a blank white screen?
Often. Blank screen + no MIME error may be missing .pck path—check Network 404s too.
Do I need HTTPS?
itch demos are HTTPS. Local file:// tests are invalid for streaming WASM behavior.
Related links
- Godot Web Export SharedArrayBuffer COOP COEP Fix
- Godot 4.5 Web Export Audio Silent First Load Fix
- Godot 4.5 Web Export CI Matrix Preflight (guide)
- Godot 4.5 WASM memory ceiling H2 2026 (blog)
- 15 Free Godot 4.5 Web Export Resources
- Official: Godot exporting for the Web, MDN WebAssembly MIME
Bookmark this page before the next jam upload—localhost green does not prove itch MIME green.