The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Debug a headless Chrome PDF by separating startup failures from page-readiness and rendering problems. First confirm how the PDF is produced and which browser version is running; then check whether the page is ready, whether print CSS is changing the layout, and whether print-color handling is altering the output.
Identify the PDF generation path first
There are two common paths to distinguish: Chrome’s command-line interface (CLI), which can print with --headless --print-to-pdf, and Puppeteer, which generates a PDF with Page.pdf(). Their controls and failure points are not interchangeable.
Before changing settings, record the installed Chrome or Chromium version, Puppeteer version if used, operating system, launch mode, and exact command or code. Keeping those details together makes it possible to compare a failing run with a working environment and to report a reproducible browser-specific issue. Current Chrome CLI documentation supports --no-pdf-header-footer; older versions may use the previous flag name, --print-to-pdf-no-header. Check the documentation for the installed version rather than assuming a flag works everywhere: Chrome headless documentation.
Chrome CLI: capture a page to a PDF
A basic command is:
chrome --headless --print-to-pdf=output.pdf https://example.com
The executable name varies by installation and operating system; use the Chrome or Chromium binary available in your environment. Chrome documents --print-to-pdf for PDF output. The command producing a file does not, by itself, prove that the page’s application content was ready when capture began.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware match#1 Best Overall
Puppeteer: generate a PDF through the API
A minimal Puppeteer flow is:
const browser = await puppeteer.launch({ headless: true });
try {
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
await page.pdf({ path: 'output.pdf' });
} finally {
await browser.close();
}
Puppeteer’s PDF method uses print CSS media by default and waits for fonts by default. Its documentation demonstrates waiting for networkidle2 before calling page.pdf(): Page.pdf() reference and PDF generation guide. Network idleness is useful, but it is not a guarantee that an application’s own asynchronous work has finished.
Rule out Chrome startup and process errors
If Chrome fails to launch, investigate the process and host before changing PDF options. A sandbox error, for example, is a startup issue—not evidence that print CSS or the page itself is broken.
Puppeteer’s troubleshooting documentation describes the Linux error No usable sandbox! when the host has no usable sandbox. It suggests --no-sandbox only when the content is absolutely trusted. Treat this as a security-sensitive workaround, not a routine launch setting; prefer fixing the host’s sandbox configuration when possible. See Puppeteer troubleshooting.
- Check that the browser executable exists and can be run by the user or service account launching it.
- Save the complete startup error and note the operating system, browser build, Puppeteer version, and launch configuration.
- Keep launch failures separate from cases where Chrome starts successfully but produces a blank, incomplete, or differently styled PDF.
Check whether the page was ready when capture began
A PDF can be blank or incomplete even when navigation has not thrown an error. The page may still be loading, or the application may populate its content after navigation using work that a generic load condition does not track.
Recommended Free Tools
Use a real-time timeout as a maximum wait, not a readiness guarantee
Chrome’s --timeout waits up to a specified maximum before capture, even if the page is still loading. It is a cap on real-time waiting; it does not mean every image, request, or application task has succeeded by the time the PDF is written. The headless documentation describes the flag and its behavior: Chrome headless documentation.
In Puppeteer, choose a navigation condition that fits the page, then wait for a concrete application signal if one exists. For example, if the page renders a report into an element with a known selector:
await page.goto('https://example.com/report', { waitUntil: 'networkidle2' });
await page.waitForSelector('[data-report-ready="true"]');
await page.pdf({ path: 'report.pdf' });
Replace that selector with a signal the application actually sets. Do not add an arbitrary delay and assume it covers every environment. Puppeteer’s PDF generation waits for fonts by default, but that does not ensure that a custom font request succeeded or that every other application task completed.
Use virtual time only for timer-driven behavior
Chrome’s --virtual-time-budget fast-forwards time-dependent JavaScript such as timers. That is different from waiting in real time with --timeout, and neither should be treated as proof of semantic readiness. If a page uses timers to reveal content, validate the resulting DOM or PDF state instead of assuming that a time budget means the intended content appeared. See Chrome headless documentation.
Rank #3
Inspect print CSS when the PDF differs from the screen
Puppeteer’s Page.pdf() uses the print CSS media type. Print-specific rules can hide elements, move them, change their size, or restyle the page. A page that looks correct in a normal browser tab may therefore produce a very different PDF.
Look for rules such as @media print and inspect whether the expected content is hidden, repositioned, or resized. To request screen media for a Puppeteer PDF, emulate it before printing:
await page.emulateMediaType('screen');
await page.pdf({ path: 'screen-styled.pdf' });
Use this as a diagnostic or a deliberate output choice. If the intended PDF should follow the site’s print layout, changing to screen media can conceal the actual print-CSS problem rather than solve it. Puppeteer documents both its default print media behavior and emulateMediaType() in the Page.pdf() reference.
Check colors and fonts independently
Print color adjustment
Puppeteer says PDF colors are modified for printing by default. If backgrounds, brand colors, or other colors look different, inspect the print styles and the page’s -webkit-print-color-adjust rules. The property can be used to force exact colors when that is the desired result; it should be applied as a considered print-style choice, not as a general fix for blank or missing content. See Puppeteer Page.pdf() documentation.
Rank #4
Missing or substituted fonts
Puppeteer waits for fonts by default during PDF generation, but a wait cannot make an unavailable font load successfully. Check the browser’s font requests and whether the runtime has access to the required system fonts. Distinguish a font-loading problem from a general page-readiness issue: a PDF may contain all the text yet show different glyphs, widths, or line breaks.
Reduce the problem to a reproducible case
When the usual checks do not explain the output, compare the failing page with a minimal local page using the same browser build and options. Keep the test narrow: first reproduce the CLI or Puppeteer path, then add the page features that change the result.
- Run the exact command or code again and preserve the full process output.
- Record navigation status, browser console messages, page errors, and the relevant page-ready state.
- Save the generated PDF and compare it with the expected result, noting whether the failure is blank output, missing content, layout changes, color changes, or no file at all.
- Repeat with a minimal page under the same Chrome version and settings. If the minimal page works, reintroduce the original page’s print CSS, fonts, and dynamic content in small steps.
- When escalating a browser-specific failure, report the exact versions, operating system, launch mode, invocation, and smallest reproducible page.
The official references used here document core controls and behaviors, not a universal error-to-fix catalogue. A concise reproduction is more actionable than assuming every PDF failure has the same cause.
Common symptoms and fixes
| Symptom | Likely branch to investigate | Next check |
|---|---|---|
| Chrome does not launch | Process startup or host configuration | Capture the startup error and verify the executable, environment, and sandbox setup. |
| PDF exists but is blank or missing late content | Page readiness | Check navigation status and wait for the application’s own ready signal, not only a fixed maximum wait or network idleness. |
| PDF layout differs from the browser screen | Print media CSS | Inspect @media print rules; compare with screen media in Puppeteer if appropriate. |
| Colors differ from the page | Print color handling | Inspect print CSS and -webkit-print-color-adjust. |
| Text is present but spacing or glyphs differ | Font loading or availability | Check font requests and fonts available to the runtime. |
| Content depends on JavaScript timers | Timer behavior versus actual readiness | Test virtual time separately and verify the resulting page state. |
Or skip the browser setup
If the task is to capture a website as an image rather than debug a PDF-printing pipeline, ScreenshotNeo provides a website screenshot API and MCP server. A one-call image request looks like this; replace the example URL with the page you need:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Best Value
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each of those steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and responses include X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. This is an alternative for capture workflows, not a replacement for diagnosing why your own headless Chrome PDF pipeline is failing. Sign up for ScreenshotNeo’s free plan.
Frequently Asked Questions
Does Puppeteer wait for fonts before generating a PDF?
Yes. Puppeteer’s PDF documentation says PDF generation waits for fonts by default; still check font requests and runtime font availability if the output differs.
What does Chrome’s virtual time budget do?
It fast-forwards timer-dependent JavaScript execution. It is distinct from a real-time timeout and does not establish that application content is ready.
Quick Recap
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.

