[Bug][Prod][Reader] PDF worker fails to load — nginx serves .mjs as application/octet-stream (strict MIME blocks the module script) #627

Closed
opened 2026-07-17 02:58:40 +00:00 by spikerj · 1 comment
Owner

Symptom

After the reader auth fix (#626 / angular PR #216), a PDF now begins to load, then fails with:

Failed to load module script: Expected a JavaScript-or-Wasm module script but the server responded with a MIME type of "application/octet-stream". Strict MIME type checking is enforced for module scripts per HTML spec.

Root cause

ngx-extended-pdf-viewer v28 (pdf.js 6.x) loads its worker/viewer as ES modulesassets/pdfjs/pdf.worker-6.0.1169*.mjs, viewer-*.mjs, pdf.sandbox-*.mjs. The SPA is served by nginx:stable-alpine3.21, whose default mime.types has no .mjs entry, so those files are sent with Content-Type: application/octet-stream. Browsers enforce strict MIME checking on module scripts and refuse to execute them → the worker never starts → the PDF can't render.

This was masked until now: pdf.js never reached worker startup because the document fetch /api/book/{id}/file was 401ing (#626). With auth fixed, the document loads and the viewer proceeds to its worker — unmasking this second, stacked bug. (.wasm is fine — nginx ≥1.21.1 maps application/wasm; only .mjs is missing.)

Fix

Add a .mjstext/javascript mapping in the SPA's nginx.config. Requires a frontend redeploy to take effect.

Fix PR: spikersoft-angular (branch off fix/pdf-viewer-auth follow-up).

## Symptom After the reader auth fix (#626 / angular PR #216), a PDF now begins to load, then fails with: > Failed to load module script: Expected a JavaScript-or-Wasm module script but the server responded with a MIME type of "application/octet-stream". Strict MIME type checking is enforced for module scripts per HTML spec. ## Root cause `ngx-extended-pdf-viewer` v28 (pdf.js 6.x) loads its worker/viewer as **ES modules** — `assets/pdfjs/pdf.worker-6.0.1169*.mjs`, `viewer-*.mjs`, `pdf.sandbox-*.mjs`. The SPA is served by `nginx:stable-alpine3.21`, whose default `mime.types` has **no `.mjs` entry**, so those files are sent with `Content-Type: application/octet-stream`. Browsers enforce strict MIME checking on module scripts and refuse to execute them → the worker never starts → the PDF can't render. This was masked until now: pdf.js never reached worker startup because the document fetch `/api/book/{id}/file` was 401ing (#626). With auth fixed, the document loads and the viewer proceeds to its worker — unmasking this second, stacked bug. (`.wasm` is fine — nginx ≥1.21.1 maps `application/wasm`; only `.mjs` is missing.) ## Fix Add a `.mjs` → `text/javascript` mapping in the SPA's `nginx.config`. Requires a frontend redeploy to take effect. Fix PR: spikersoft-angular (branch off `fix/pdf-viewer-auth` follow-up).
Author
Owner

Resolved in spikersoft-angular PR #217 (merged to master) and deployed + verified:

$ curl -sI https://learn.spikersoft.com/assets/pdfjs/pdf.worker-6.0.1169.min.mjs
HTTP/2 200
content-type: text/javascript

The worker no longer comes back as application/octet-stream, so the module loads and the PDF chain (auth #626 + this MIME fix) works end to end. Closing.

Resolved in spikersoft-angular PR #217 (merged to `master`) and **deployed + verified**: ``` $ curl -sI https://learn.spikersoft.com/assets/pdfjs/pdf.worker-6.0.1169.min.mjs HTTP/2 200 content-type: text/javascript ``` The worker no longer comes back as `application/octet-stream`, so the module loads and the PDF chain (auth #626 + this MIME fix) works end to end. Closing.
Sign in to join this conversation.