It will not run
Navigation timeout of 30000 ms exceeded
The render throws after exactly thirty seconds. Often it works for most documents and fails for the large ones, or fails intermittently under load.
What is actually happening
The default wait condition is the network going idle, and something on the page is keeping it busy: an analytics beacon, a font request to a host that is not responding, a polling request, or an ad script. The page is visually finished long before the network agrees.
Confirming it is this and not something that looks like it
Log the outstanding requests when the timeout fires. It is almost always a third-party host rather than your own content.
The fix
Remove everything from the document that is not the document. A rendered document should make no third-party requests at all: no analytics, no tag manager, no chat widget, no font from a public CDN. This is faster and more reliable than raising the timeout, which only makes the failure take longer.
<!-- A document template starts empty and adds only what the document needs.
Copying the app layout is what brings all of this in. -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- No analytics. No tag manager. No chat widget. No CDN font. -->
<style>/* inlined document CSS */</style>
</head>
<body>
<!-- Content only. -->
</body>
</html>If that was not it
These produce the same symptom often enough to be worth ruling out before assuming the fix above did not work.
- A font from a public CDN, which is a third-party request like any other
- An image on a host that is slow or blocking non-browser user agents
- A service worker registration, which holds the network open
- Long polling or a websocket, which never goes idle by definition
Frequently asked
Does this happen with every rendering engine?
The behaviour behind it is not specific to one tool. The default wait condition is the network going idle, and something on the page is keeping it busy: an analytics beacon, a font request to a host that is not responding, a polling request, or an ad script. Anything rendering HTML to a paged medium has to make the same decision, so the fix travels with you if you change how the render happens.
Will this show up as an error in my logs?
Yes, this one surfaces as a thrown error or a failed status, which is why it is at least findable. The harder half is that the message often names the call that was in flight rather than the thing that actually failed.
Related failures
Problems people arrive at from the same starting point, or mistake for this one.
Failed to launch the browser process
A headless browser is not a self-contained binary.
libnss3.so: cannot open shared object file
This is the previous error with the first missing library named.
Protocol error (Page.printToPDF): Target closed
The tab crashed, and by far the most common reason is memory.
Chromium does not fit in an AWS Lambda deployment package
A full browser build is several hundred megabytes and the unzipped package limit is 250MB.
PDF generation runs out of memory
Two multiplying factors.
CSS for paged documents, and what actually works
Which parts of the paged media specification a browser-based render implements.
Everything that goes wrong, by category
The full list, grouped by where in the pipeline it breaks.
Paste your markup and see the rendered document, without signing up.