2026-10-02 · Q&A guide

Fix PDF.js Unexpected Server Response (0) When Loading Remote PDFs

Learn why PDF.js throws an unexpected server response and how to correctly enable CORS or proxy your PDF files.

1. What Causes the 0‑Response Error

When PDF.js requests a file, the browser expects a 200 OK response with the PDF binary. If the request fails, the network stack reports status 0. This can happen for network errors, blocked CORS, or an opaque response from a no‑cors fetch.

2. Why Setting `mode: 'no-cors'` Doesn’t Work

The `no-cors` mode turns the response into an opaque blob that PDF.js cannot read. The viewer will show the error message and never load the document. PDF.js requires a readable response stream, so you must allow cross‑origin access through proper headers.

// Example fetch that would fail with no‑cors
fetch('http://100.0.55.10/file.pdf', { mode: 'no-cors' })
  .then(r => console.log(r.type)) // "opaque"

3. Enable Correct CORS Headers on the PDF Server

Configure the server that hosts the PDFs to send the `Access-Control-Allow-Origin` header. For a wildcard origin (any site), use `*`. If you want stricter control, specify your viewer domain. The header must be sent with the 200 OK response.

// Apache (.htaccess)
<Files "*.pdf">
  Header set Access-Control-Allow-Origin "*"
</Files>

// Nginx
location ~* \.pdf$ {
  add_header Access-Control-Allow-Origin *;
}

// Express.js
app.get('/files/:name.pdf', (req, res) => {
  res.set('Access-Control-Allow-Origin', '*');
  res.sendFile(path.join(__dirname, 'pdfs', req.params.name + '.pdf'));
});

4. Use a Same‑Origin Proxy When You Can’t Modify Headers

If you cannot control the remote server, route the PDF through your own backend. The proxy fetches the file, attaches the correct CORS header, and streams it to the viewer. This keeps the browser’s same‑origin policy satisfied.

// Node.js proxy example
const express = require('express');
const request = require('request');
const app = express();

app.get('/proxy/:file', (req, res) => {
  const url = `http://100.0.55.10/pdfFolder/${req.params.file}.pdf`;
  request({ url, encoding: null })
    .on('response', r => {
      res.set('Content-Type', 'application/pdf');
      res.set('Access-Control-Allow-Origin', '*');
    })
    .pipe(res);
});

app.listen(3000);

5. Verify the Fix with Browser DevTools

Open the Network tab, reload the viewer, and inspect the PDF request. The status should be 200, the `Content-Type` should be `application/pdf`, and the `Access-Control-Allow-Origin` header must be present. If you still see status 0, double‑check the URL and ensure the server is reachable.

Takeaway: To load PDFs from another server, provide proper CORS headers or route the file through a same‑origin proxy; `no-cors` mode blocks PDF.js from accessing the data.

People also ask

Can I use a wildcard `*` for `Access-Control-Allow-Origin`?

Yes, but it allows any site to fetch the PDF. For tighter security, specify the exact origin of your viewer.

What if the PDF server is on HTTPS and my viewer is HTTP?

Mixed content is blocked by browsers. Serve the viewer over HTTPS or use a proxy that also uses HTTPS.

Inspired by a public discussion on Stack Overflow. This article is an original explanation for learners.

← All posts