Troubleshooting
Relevant source files
The following files were used as context for generating this wiki page:This document provides guidance for diagnosing and resolving common issues encountered when using Rendertron. It covers problems related to configuration, rendering behavior, environment setup, and middleware integration. For issues specific to running Headless Chrome in your environment (especially within Docker), refer to the official Puppeteer troubleshooting guide.
Sources: README.md:120-122
Common HTTP Status Codes
When a request to the Rendertron service fails, it will respond with an HTTP status code indicating the nature of the problem. Understanding these codes is the first step in debugging.
| Status Code | Reason | Source File(s) |
|---|---|---|
400 Bad Request | The renderer could not get a valid response from the target URL. This can happen if the URL is malformed or points to an unreachable domain (e.g., http://unknown.blah.com). It also occurs if the page is about:blank. | src/test/app-test.ts:160-163(), src/renderer.ts:121-126() |
403 Forbidden | The requested URL is disallowed. Rendertron restricts requests to non-HTTP/HTTPS protocols (e.g., file:///) to prevent local file system access. It also blocks requests that appear to be accessing Google Cloud metadata endpoints. | src/rendertron.ts:77-87(), src/test/app-test.ts:165-173(), src/renderer.ts:128-132() |
404 Not Found | The Rendertron service will forward the status code from the page being rendered. If you render a URL that returns a 404, Rendertron will also return a 404. | src/test/app-test.ts:111-114() |
500 Internal Server Error | An error occurred during the screenshot process, such as a timeout or other Puppeteer-related issue. | src/rendertron.ts:127-130() |
Overriding Status Codes
You can override a 200 OK status code by including a specific meta tag in the HTML of the page being rendered. Rendertron will parse this tag and use its value as the final status code. If multiple tags exist, the first one found is used. Note that this does not apply if the initial response status is not 200 or 304.
<meta name="render:status_code" content="401" />
This is useful for signaling to crawlers that a page is, for example, not found or requires authentication, even if the single-page application shell itself loaded successfully.
Sources: src/renderer.ts:137-143, test-resources/http-meta-status-code.html, test-resources/http-meta-status-code-multiple.html
Rendering and Content Issues
Rendering Timeout
Rendertron has a timeout for rendering a page, which defaults to 10,000 milliseconds (10 seconds). If a page takes longer than this to reach the networkidle0 state (no network requests for 500ms), the rendering process will be aborted. In this case, Rendertron will attempt to return whatever content has been rendered so far.
This diagram shows the render request flow and where a timeout can occur.
To fix timeout issues, you can either optimize the target page's load performance or increase the timeout value in the configuration.
Sources: README.md:65-67, src/config.ts:28, src/renderer.ts:110-114
Web Components and Shadow DOM
Headless Chrome's serialization of Shadow DOM can be problematic. Rendertron requires the use of the Shady DOM polyfill to ensure web components are rendered correctly.
- For Web Components v1: If you are using
webcomponents-lite.jsorwebcomponents-loader.js, you must add thewc-inject-shadydom=truequery parameter to your render requests. This forces Rendertron to inject the necessary polyfills. - For Web Components v0 (deprecated): Shady DOM is typically enabled by default in libraries like Polymer 1.x.
The renderer.ts file explicitly injects scripts to force the polyfills when rendering.
// src/renderer.ts:92-94
page.evaluateOnNewDocument('customElements.forcePolyfill = true');
page.evaluateOnNewDocument('ShadyDOM = {force: true}');
page.evaluateOnNewDocument('ShadyCSS = {shimcssproperties: true}');
Sources: README.md:69-80, src/renderer.ts:92-94, src/test/app-test.ts:60-64
Stripped Content
To prevent unintended script execution on the client after rendering, Rendertron strips certain tags from the final serialized HTML.
- Stripped:
<script>tags (unlesstypeisapplication/ld+json) and<link rel="import">tags. - Not Stripped:
<script type="application/ld+json">tags are preserved to support structured data for SEO.
If your page relies on client-side JavaScript that is being stripped, it will not function correctly after being served from Rendertron. The rendering must be complete before serialization.
Sources: src/renderer.ts:40-46, src/test/app-test.ts:92-105
Configuration
Configuration issues can prevent the service from starting or cause it to behave unexpectedly. Rendertron is configured via a config.json file in the project root.
| Property | Type | Default | Description |
|---|---|---|---|
datastoreCache | boolean | false | Enable caching with Google Cloud Datastore. |
timeout | number | 10000 | Render timeout in milliseconds. |
port | string | 3000 | Port for the Rendertron service. Overridden by process.env.PORT. |
width | number | 1000 | Viewport width for rendering. |
height | number | 1000 | Viewport height for rendering. |
Sources: src/config.ts:24-32, README.md:113-119
Middleware Problems
The Express middleware is a common source of issues. It acts as a gatekeeper, deciding which requests to proxy to the Rendertron service.
This diagram illustrates the middleware's decision logic.
Common configuration mistakes include:
proxyUrlis missing or incorrect: This is a required field and must point to your running Rendertron instance.userAgentPatternis too restrictive or too permissive: By default, it matches a list of common bots. If a bot you care about is not on the list, it won't be prerendered.excludeUrlPatternblocks necessary routes: By default, it excludes common static file extensions (e.g.,.js,.css,.png). Ensure it doesn't accidentally match API routes or page URLs that need rendering.timeoutis too short: The middleware has its own timeout (default 11000ms). If the request to Rendertron exceeds this, it will fall through and serve the non-prerendered content.
Sources: middleware/README.md, middleware/src/test/middleware-test.ts:145-151
Environment and Setup
- Node.js Version: The project requires a Node.js version between 7 and 11 (
>=7 <11). Using a different version may cause dependency or runtime errors.
Sources: package.json:6-8 - Health Check: Rendertron exposes a
/_ah/healthendpoint. If you can access this endpoint and receive a200 OKresponse, the core server is running.
Sources: src/rendertron.ts:48-49, src/test/app-test.ts:38-41 - URL Restrictions: Ensure the URLs you are trying to render use
httporhttps. Other protocols likefile://are forbidden.
Sources: src/rendertron.ts:77-87