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

An empty Chrome headless PDF usually means Chrome printed before a client-rendered page finished, or the page’s print stylesheet hid what you saw on screen. First verify the serialized DOM, then add a bounded capture delay or (with Puppeteer) wait for an application-specific ready state. If the DOM and screenshot contain content but the PDF does not, inspect print CSS, fonts, backgrounds and the Chromium build.

The commands and code below cover Chrome’s command-line interface and Puppeteer, including diagnostics for intermittent failures.

Start by identifying which layer is empty

Run a DOM diagnostic before changing PDF options:

chrome --headless --dump-dom https://example.test/report

Save the output and compare it with a headless screenshot and the PDF. This separates application rendering failures from print rendering failures.

What you observe Most likely cause Next action
Dumped DOM and screenshot are empty Wrong URL, authentication failure, JavaScript error, failed data request or capture before rendering Check the URL and requests, then add an explicit readiness wait
DOM and screenshot contain the report, PDF is empty @media print rules, print colors, dimensions or a browser regression Inspect print CSS and test another current Chromium build
Text appears but styling is missing Fonts or stylesheets were not ready; backgrounds are disabled Wait for fonts, verify stylesheet requests and enable print backgrounds
Success varies between runs Fixed sleep is racing asynchronous rendering Use a semantic ready marker plus network-idle and font waits

A PDF viewer cannot restore content that was never painted. Keep the three artifacts—DOM, screenshot and PDF—for the same URL and browser build while diagnosing.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Brother DCP-L2640DW Wireless Compact Monochrome Multi-Function Printer, Copy, Scan, Duplex, Mobile Printing
  • BEST FOR SMALL BUSINESSES – Engineered for extraordinary productivity, the Brother DCP-L2640DW Monochrome (Black & White) 3-in-1 combines laser printer, scanner, copier in one compact footprint and delivers high-quality black & white prints
  • FAST PRINTER WITH EFFICIENT SCANNING – Produces documents quickly with print speeds up to 36 ppm(2) and scan speeds up to 23.6/7.9 ipm(3) (black/color). A 50-page auto document feeder(4) allows for convenient, time saving multi-page scanning and copying
  • FLEXIBLE CONNECTION OPTIONS – Easily navigate the changing demands of your business with secure multi-device connectivity via built-in dual-band wireless (2.4GHz / 5GHz) and Ethernet. Or connect locally to a single computer via USB interface
  • BROTHER MOBILE CONNECT APP – Print, scan, and manage your wireless printer anytime, from almost anywhere from your mobile device. Order Brother Genuine Supplies, track toner usage, and complete more work on-the-go(5)
  • CHOOSE BROTHER GENUINE TONER – When it’s time to replace your toner, be sure to choose Brother Genuine TN830 or TN830XL replacement toner. And with Refresh EZ Print Subscription Service, you’ll never worry about running out of toner again and you’ll enjoy savings of up to 50%(6) on Brother Genuine Toner. Get started with Refresh today with a Free Trial(1)

Fixing Chrome’s command-line print-to-PDF

1. Confirm the URL and output path

Use a fully qualified URL, verify that the page does not require an interactive login, and make sure the destination directory is writable. A failed navigation can otherwise look like a PDF problem.

2. Add a bounded capture delay

Chrome captures at page-load completion unless you provide a timeout or virtual-time budget. The --timeout value is a maximum wait in milliseconds before content is captured, even if the page is still loading. Start with a value appropriate to the application, such as 5,000 milliseconds:

chrome --headless --disable-gpu 
  --print-to-pdf=output.pdf 
  --no-pdf-header-footer 
  --timeout=5000 
  https://example.test/report

Increase the value only when observation shows that the application needs longer. A timeout is not a readiness test: it does not know whether the final data, components or images have appeared.

3. Fast-forward timer-driven pages

Pages that rely on setTimeout or setInterval can benefit from virtual time:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
chrome --headless --disable-gpu 
  --print-to-pdf=output.pdf 
  --no-pdf-header-footer 
  --virtual-time-budget=5000 
  https://example.test/report

Virtual time fast-forwards timer-dependent code; it is different from waiting for real network activity. Use it for deterministic timer-driven rendering, not as a substitute for authentication or a missing API response.

Rank #2
Brother HL-L2405W Wireless Compact Monochrome Laser Printer with Mobile Printing, Black & White Output | Includes Refresh Subscription Trial(1), Works with Alexa
  • BEST FOR HOMES & HOME OFFICES – Engineered for consistent, premium print quality, the Brother HL-L2405W Monochrome (Black & White) Laser Printer delivers sharp, crisp prints at an affordable price. Prints one-sided documents at speeds up to 30ppm(2)
  • COMPACT, CONNECTED PRINTER – Flexible connection options make this an ideal printer for home use and at-home offices. Securely connect to multiple devices with built-in dual-band wireless (2.4GHz/5GHz) or locally to a single computer via USB interface
  • BROTHER MOBILE CONNECT APP – Manage your printer remotely and print from your mobile device anytime, from almost anywhere. Order Brother Genuine Supplies, track toner usage, and complete more work on-the-go(3)
  • VERSATILE PAPER HANDLING – Enjoy seamless, reliable everyday printing with the 250-sheet paper tray(4) and a manual feed slot that enables printing on envelopes and specialty pape
  • BROTHER IS AT YOUR SIDE – Backed by Brother with a 1-year limited warranty and free online, call, or live chat support for the life of your printer

4. Use the current header/footer switch

Use --no-pdf-header-footer when you do not want Chrome’s printed header and footer. Older Chrome versions used --print-to-pdf-no-header; scripts that still use the older spelling should be checked against the installed build.

5. Compare all three outputs

Generate a screenshot and dump the DOM with the same URL and timing options. If both are empty, investigate application readiness, JavaScript errors and failed requests. If they are populated while the PDF is blank, move to print-CSS checks instead of adding longer sleeps.

Make Puppeteer wait for the application, not just the network

Puppeteer’s PDF guide commonly navigates with waitUntil: 'networkidle2' and then calls page.pdf(). Network idle can occur before a framework finishes processing fetched data, so add a selector that represents the completed report whenever possible.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const puppeteer = require('puppeteer');

(async () => {
  const url = 'https://example.test/report';
  const browser = await puppeteer.launch({headless: true});
  const page = await browser.newPage();

  page.on('console', message => {
    console.log(`[console:${message.type()}] ${message.text()}`);
  });
  page.on('requestfailed', request => {
    console.error('request failed:', request.url(), request.failure());
  });

  try {
    await page.goto(url, {
      waitUntil: 'networkidle2',
      timeout: 60000
    });
    await page.waitForSelector('#report-ready', {
      visible: true,
      timeout: 30000
    });
    await page.waitForNetworkIdle({idleTime: 500, timeout: 30000});

    await page.pdf({
      path: 'report.pdf',
      printBackground: true,
      preferCSSPageSize: true,
      waitForFonts: true
    });
  } finally {
    await browser.close();
  }
})();

Replace #report-ready with a selector your application sets only after the final render. For example, application code can add data-pdf-ready="true" to a container after its last data and component update. This is more reliable than choosing a delay that happens to work on one run.

page.waitForSelector() can require visibility and throws when its timeout expires. page.waitForNetworkIdle() waits for the configured idle period, but it still cannot infer that your application has consumed the response. The example also logs browser-console messages and failed requests so a blank capture leaves evidence.

Rank #3
Canon imageCLASS LBP6030w - Monochrome Single-Function Wireless Compact Wireless Laser Printer, 1 Year Limited Warranty, 19 PPM, White - Print Only
  • FAST PRINT SPEEDS: Print up to 19 pages per minute.
  • COMPACT DESIGN: Space-saving, compact design fits anywhere in your home, school or small office.
  • WIRELESS CONNECTIVITY: Print from almost anywhere in your workspace using your compatible mobile device.
  • PAPER CAPACITY: Up to 150 sheets.
  • SUSTAINABILITY: Uses less than 2 watts in Energy Saver mode.

Correct print CSS and PDF options

Puppeteer generates PDFs using the print CSS media type by default. A page can therefore look correct in a normal browser window while its print representation hides the report.

Inspect rules that remove or recolor content

  • Search @media print for display: none or visibility: hidden on report containers.
  • Check for zero heights, clipping and off-screen positioning.
  • Look for white text or low-contrast colors on white paper.
  • Verify that a print-only container is actually populated before capture.

If the screen design is intentionally the output you need, switch media before printing:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
await page.emulateMediaType('screen');
await page.pdf({path: 'report.pdf', printBackground: true});

Use printBackground: true when the report depends on CSS background fills or images; the default is false. Use preferCSSPageSize: true when your stylesheet defines the paper size with an @page rule. Keep waitForFonts: true so PDF generation waits for document.fonts.ready; current Puppeteer PDF options list it as true by default, but setting it explicitly documents your intent and protects scripts that move between versions.

Check browser-version regressions

Record the exact Chrome or Chromium version whenever a failure occurs. Chromium issue 362301064 was filed on 2024-08-27 after a report that print-to-PDF stopped working with the default headless mode; the report said --headless=old worked around it, and the issue is marked fixed. Treat that workaround as historical, not a permanent recipe. Reproduce with a current stable build and, if possible, a known-good build before rewriting page code.

Choosing CLI or Puppeteer

Requirement Chrome CLI Puppeteer
Readiness control Bounded --timeout or virtual-time budget Semantic selectors, network-idle waits and application logic
Print styling Controlled by page CSS and command switches Can emulate screen media and set PDF options directly
Fonts and backgrounds Must be ready when capture starts waitForFonts and printBackground are explicit options
Observability Compare DOM, screenshot and PDF externally Capture console and request-failure events in the script
Version sensitivity Depends directly on the installed Chrome build Depends on both Puppeteer and its Chromium build

Use the CLI for simple, stable pages and automation where a bounded delay is acceptable. Use Puppeteer when readiness depends on application state, authentication setup, media emulation or diagnostics.

Rank #4
Brother HL-L2460DW Wireless Compact Monochrome Laser Printer with Duplex, Mobile Printing, Black & White Output | Includes Refresh Subscription Trial(1), Works with Alexa
  • BEST FOR HOME OFFICES & SMALL TEAMS – Engineered for consistent, premium print quality, the Brother HL-L2460DW Monochrome (Black & White) Laser Printer produces documents that are clear, crisp, and easy to review and share, all at an affordable price
  • COMPACT, CONNECTED, EXCEPTIONALLY EFFICIENT– Connect with built-in dual-band wireless (2.4GHz/5GHz), Ethernet, or to a single computer via USB interface. Prints at speeds up to 36ppm(2), plus automatic duplex printing saves time and reduces paper waste
  • BROTHER MOBILE CONNECT APP – Manage your wireless printer remotely and print from your mobile device anytime, from almost anywhere. Order Brother Genuine Supplies, track toner usage, and complete more work on-the-go(3)
  • VERSATILE PAPER HANDLING – Tackle high-volume black & white printing with the 250-sheet capacity paper tray.(4) The manual feed slot enables printing on envelopes and specialty paper
  • BROTHER IS AT YOUR SIDE – Backed by Brother with a 1-year limited warranty and free online, call, or live chat support for the life of your printer
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting common failures

The DOM is empty

Check redirects, credentials, JavaScript errors and API responses first. Confirm that the URL is the same one a normal browser can load without an interaction that headless Chrome cannot perform. Add logging in Puppeteer and inspect failed requests before changing PDF flags.

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

The selector wait times out

The selector may be wrong, never become visible, or be rendered only after an API call that failed. Inspect the page’s final HTML and network failures. If the application has no reliable marker, add one at the point where the final render completes rather than increasing the timeout indefinitely.

Screenshot works but PDF is blank

Review @media print, hidden containers, zero dimensions and print colors. Try page.emulateMediaType('screen') as a diagnostic, then decide whether the print stylesheet should be corrected or screen media is genuinely required.

Text exists but images or colors do not

Wait for fonts, confirm stylesheet requests succeeded, and set printBackground: true. For lazy-loaded images, ensure the page has actually scrolled or otherwise triggered the loading behavior before the ready marker is set.

Only some runs are blank

Replace a single fixed sleep with a visible ready selector, a short network-idle wait and font readiness. Keep console and request-failure logs so intermittent data or script failures can be correlated with the capture.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
HP LaserJet M110w Wireless Black & White Printer, Print, Fast speeds, Easy Setup, Mobile Printing, Best-for-Small Teams
  • FROM AMERICA'S MOST TRUSTED PRINTER BRAND – Perfect for small teams printing professional-quality black & white documents and reports. Perfect for 1-3 people
  • WORLD'S SMALLEST LASER IN ITS CLASS – Precision laser printing that fits anywhere
  • FAST PRINT SPEEDS – Up to 21 black-and-white pages per minute single-sided
  • WIRELESS WITH SELF-RESET – Helps you stay connected
  • PRINT FROM ANY DEVICE – Wireless printing from any mobile device, PC or tablet. Works with Microsoft, Mac, AirPrint, Android, Chromebook and more

A previously working command broke after an upgrade

Save the browser version, test a current stable release and compare with a known-good build. Do not assume an old headless-mode workaround applies to current Chrome.

Or skip the browser setup

ScreenshotNeo provides a website screenshot API and MCP server when you need a clean capture without maintaining Chrome timing and print-CSS code. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the page verdict and billing status in X-Page-Verdict and X-Billed headers.

For a screenshot or PDF-style workflow, make one request (replace the target URL):

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

See the complete parameter reference and PDF options in the ScreenshotNeo documentation. Options include full-page capture with lazy images loaded, CSS-selector element capture, device and viewport controls, retina scale, PDF paper settings and page ranges, custom CSS or JavaScript, click and wait conditions, blocked resources, headers and cookies, timezone and geolocation, transparent backgrounds, resizing, selectable cache TTLs, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, usage reporting and an OpenAPI specification. An MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients.

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.

The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; yearly billing provides two months free. Every feature is available on every plan. Create a free ScreenshotNeo account to try the 1,000 included shots.

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.