October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
JavaScript

How to Fix Damaged PDFs Returned as Puppeteer Blob Responses

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If a PDF downloaded from a Puppeteer-backed endpoint is damaged, first find the boundary where its bytes change. page.pdf() returns PDF bytes as a Uint8Array; keep those bytes binary through your server response and browser download. Check the HTTP status before treating a response as a PDF, and do not stringify or UTF-8-decode the payload. If you are capturing an existing PDF response instead of generating one, test that path separately: Puppeteer documents that response buffers may be re-encoded by the browser.

First identify which PDF path you are using

“Puppeteer returned a damaged PDF” can describe two different operations. They have different likely failure points, so establish which one your code performs before changing headers or Blob handling.

Generating a PDF with page.pdf()

page.pdf() generates a PDF and resolves to a Uint8Array. Treat the result as binary data. Pass it directly to the HTTP response or write it to a file; do not convert it to a string or put it in a JSON object. Puppeteer also provides page.createPDFStream(), which returns a ReadableStream<Uint8Array>. That is another binary path, not text.

Capturing a PDF from an existing page response

If the page navigates to a PDF and you collect its network response with Puppeteer, you are not using page.pdf(). Puppeteer’s HTTPResponse.buffer() and content() return response-body bytes, but the browser may re-encode the buffer based on headers or heuristics; failed encoding detection can produce incorrect bytes. Check this capture path early rather than assuming the Blob constructor caused the damage.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
MixPad Free Multitrack Recording Studio and Music Mixing Software [Download]
  • Create a mix using audio, music and voice tracks and recordings.
  • Customize your tracks with amazing effects and helpful editing tools.
  • Use tools like the Beat Maker and Midi Creator.
  • Work efficiently by using Bookmarks and tools like Effect Chain, which allow you to apply multiple effects at a time
  • Use one of the many other NCH multimedia applications that are integrated with MixPad.

Trace the bytes from generation to download

Compare the payload at each handoff: Puppeteer output, server response body, browser Blob or ArrayBuffer, and final saved file. Record byte lengths and, in a local diagnostic environment, cryptographic digests at those boundaries. The first point where length or digest changes narrows the fault. Do not log PDF contents: even a diagnostic PDF may contain private data.

  1. Inspect Puppeteer’s result. For a generated PDF, note the returned byte length before the HTTP framework sees it. For a captured response, record the requested URL, response status, relevant headers, and byte length.
  2. Inspect the server boundary. Confirm the route sends the same bytes it received, not a serialized representation. Compare the response body’s length or digest with the original.
  3. Inspect the browser boundary. After checking the HTTP status, compare the Blob’s size or the ArrayBuffer’s byte length with the server’s response.
  4. Validate the saved artifact. Open the complete file in a PDF reader or run it through a PDF parser or validator available in your environment. A file extension or MIME type alone does not prove the payload is a valid PDF.

As a quick heuristic, a file whose first bytes do not look like a PDF may actually be an HTML login page, JSON error, proxy message, or other non-PDF response. This is a clue, not a complete validity test: inspect the status and content type, then validate the full artifact.

Preserve bytes in the server response

Here is a minimal Node.js and Express example for generating a PDF and returning it as a download. It keeps Puppeteer’s byte output intact and sets response metadata separately from the payload.

import express from 'express';
import puppeteer from 'puppeteer';

const app = express();

app.get('/document.pdf', async (req, res, next) => {
  let browser;
  try {
    browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('https://example.com', { waitUntil: 'networkidle0' });

    const pdfBytes = await page.pdf({ format: 'A4', printBackground: true });
    res.status(200);
    res.set({
      'Content-Type': 'application/pdf',
      'Content-Disposition': 'attachment; filename="document.pdf"'
    });
    res.end(Buffer.from(pdfBytes));
  } catch (error) {
    next(error);
  } finally {
    await browser?.close();
  }
});

app.listen(3000);

Replace the example URL with the page you intend to render. If your framework accepts a Uint8Array directly, that may also be suitable; the important condition is that the response body remain the original bytes. Wrapping in Buffer.from() makes the binary intent explicit in this Node example. Avoid res.send(JSON.stringify(pdfBytes)), pdfBytes.toString(), and string interpolation around the payload.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Response headers are not a repair tool

Use Content-Type: application/pdf to identify the media type. For a download prompt, set an appropriate Content-Disposition: attachment; filename="document.pdf". Content-Encoding is a separate concern: it describes how the representation is encoded for transport. Ensure it matches any compression actually applied. Correct headers help clients interpret bytes, but cannot restore bytes that were already altered or truncated.

Read a browser response as binary data

On the client, check for an HTTP error before creating a Blob or saving a file. A successful transport can carry an application-level error body, such as a login page or JSON error. Do not call response.text() on a response you believe is a PDF just to inspect it; interpreting binary data as text is not a safe PDF diagnostic.

const response = await fetch('/document.pdf');

if (!response.ok) {
  const contentType = response.headers.get('content-type') || '';
  const message = contentType.includes('application/json')
    ? JSON.stringify(await response.json())
    : `Request failed: ${response.status} ${response.statusText}`;
  throw new Error(message);
}

const contentType = response.headers.get('content-type') || '';
if (!contentType.includes('application/pdf')) {
  throw new Error(`Expected application/pdf; received ${contentType || 'no Content-Type'}`);
}

const pdfBlob = await response.blob();
if (pdfBlob.size === 0) {
  throw new Error('The PDF response was empty');
}

const objectUrl = URL.createObjectURL(pdfBlob);
const link = document.createElement('a');
link.href = objectUrl;
link.download = 'document.pdf';
document.body.append(link);
link.click();
link.remove();
// Revoke the object URL after the download consumer has had a chance to use it.
setTimeout(() => URL.revokeObjectURL(objectUrl), 1000);

The delay here is a conservative example, not a universal lifecycle guarantee. If your application has a more explicit download-completion signal, use it before revoking the URL. The key diagnostic point is to create the object URL from the final Blob and not revoke it before the browser can use it.

Blob or ArrayBuffer?

response.blob() reads the body to completion and returns a Blob containing those body bytes. Its type is derived from the response’s Content-Type; the type label does not validate the contents. response.arrayBuffer() also consumes the body and exposes its bytes for downstream processing. Choose based on what the next step needs: a Blob is convenient for browser download or display, while an ArrayBuffer is useful when code needs byte-oriented processing. Either can preserve a valid response; neither repairs a corrupted one.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When using Puppeteer to capture a PDF response

If you are retrieving a PDF served by another site, inspect the response itself before building a download around it. Confirm that it is the expected URL and status, and inspect Content-Type and Content-Encoding independently. Then compare the response bytes with the final saved bytes. The documented Puppeteer re-encoding caveat makes this branch materially different from generating a fresh PDF with page.pdf().

Rank #4
DeskFX Free Audio Effects & Audio Enhancer Software [PC Download]
  • Transform audio playing via your speakers and headphones
  • Improve sound quality by adjusting it with effects
  • Take control over the sound playing through audio hardware

Also verify the response is really a PDF. Authentication redirects, access-denied pages, bot checks, and server errors can produce non-PDF content even when your browser automation completed and your code received a response. Check status and headers first. If it is clearly an error response, inspect a short text or JSON diagnostic representation; do not decode a response you have established to be a PDF as text.

Choose full-buffer or stream handling deliberately

A full-buffer result such as Uint8Array or Node’s Buffer is straightforward when the endpoint needs the complete PDF before responding. Puppeteer’s createPDFStream() provides a stream of byte chunks, which can suit an application designed to pass a stream through. Both approaches require byte-preserving handling. A stream does not by itself prevent encoding mistakes, and a full buffer does not imply corruption. Consider application memory and response design for your document sizes; the documentation cited here does not establish a universal size threshold or quantified performance difference.

Troubleshoot by symptom

Symptom Likely explanation What to check or change
The downloaded file contains readable HTML or JSON The endpoint returned an error, login, or proxy response rather than a PDF. Check status and content type before calling blob(). Fix the underlying request or authentication failure.
The file is much smaller than expected or empty The response may be empty, truncated, or an error body. Compare byte lengths at the Puppeteer, server, and client boundaries; check status and server logs.
The PDF works on the server but not after download A server or client handoff may have transformed the bytes. Compare local diagnostic digests at each boundary. Search for string conversion, JSON serialization, or incorrect base64 decoding.
The PDF is corrupted only when captured from a page The capture route uses an HTTP response buffer, which has a documented browser re-encoding caveat. Inspect headers and bytes for the original response; distinguish it from a PDF generated by page.pdf().
The browser displays or downloads the wrong thing Incorrect or missing media-type metadata can affect interpretation, or the payload is not actually a PDF. Set Content-Type: application/pdf for PDF bytes and verify the body independently.
arrayBuffer() rejects Body decoding may fail, including when Content-Encoding is incorrect. Check whether the response is compressed and whether its encoding header accurately describes it.
The PDF is valid but opens inline instead of downloading The response is being presented rather than forced as an attachment. Use Content-Disposition: attachment with a filename. This changes presentation, not PDF integrity.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your task is to capture a website screenshot rather than generate or repair a PDF, ScreenshotNeo offers a one-request screenshot API. It is not a fix for a damaged Puppeteer PDF or a replacement for PDF generation. ScreenshotNeo accepts cookie/consent banners and removes known consent platforms, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are not billed. It also provides an MCP server for AI agents. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000. See the ScreenshotNeo API documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Try ScreenshotNeo free: sign up for 1,000 screenshots a month with no card.

Best Value
MixPad Multitrack Recording Software for Sound Mixing and Music Production Free [Mac Download]
  • Mix an audio, music and voice tracks
  • Record single or multiple tracks simultaneously
  • Intuitive tools to split, trim, join, and many other editing features
  • Loaded with audio effects including EQ, compression, reverb, and more.
  • Load an audio file and export to all popular audio formats from studio quality wav to high compression formats

Match behavior to your installed Puppeteer version

The current documentation results for Page.pdf() and HTTPResponse identify versions 25.12.0 and 25.10.0 respectively. Your installed version may be older, and the documentation does not establish which version your application runs. Check the API behavior and signatures against the version in your project before applying a change, especially on the response-capture path. The diagnostic sequence still applies: establish the path, verify bytes at boundaries, and separate payload integrity from response metadata.

Frequently Asked Questions

Does setting the Blob type to application/pdf fix a damaged PDF?

No. A Blob type describes the media type; it does not change or validate the bytes it contains.

Why can a PDF endpoint return HTTP 200 but still produce a bad download?

HTTP success only establishes that the request completed successfully at the transport level. The body can still be an application error page or altered payload, so inspect its type and bytes.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should I use ScreenshotNeo to repair a Puppeteer PDF?

No. ScreenshotNeo captures website screenshots; it is not a PDF repair or PDF-generation service.

Quick Recap

Bestseller No. 1
MixPad Free Multitrack Recording Studio and Music Mixing Software [Download]
MixPad Free Multitrack Recording Studio and Music Mixing Software [Download]
Create a mix using audio, music and voice tracks and recordings.; Customize your tracks with amazing effects and helpful editing tools.
Bestseller No. 4
DeskFX Free Audio Effects & Audio Enhancer Software [PC Download]
DeskFX Free Audio Effects & Audio Enhancer Software [PC Download]
Transform audio playing via your speakers and headphones; Improve sound quality by adjusting it with effects
Bestseller No. 5
MixPad Multitrack Recording Software for Sound Mixing and Music Production Free [Mac Download]
MixPad Multitrack Recording Software for Sound Mixing and Music Production Free [Mac Download]
Mix an audio, music and voice tracks; Record single or multiple tracks simultaneously; Intuitive tools to split, trim, join, and many other editing features

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.