withastro/astro · error · Error

Failed to prerender

Error message

Failed to prerender ${request.url}: ${prerenderError}

What it means

When the Cloudflare adapter prerenders a URL, the workerd handler reports exceptions through an `x-astro-prerender-error` response header, because the Vite preview server may strip the error body. The Node side checks that header first and rethrows the remote error wrapped in this message. Non-2xx statuses alone are not errors here — only the header marks failure, since pages like a custom 404 may intentionally return non-200 while prerendering.

Solutions

  1. Read the prerenderError text — it is the original exception message/stack from inside workerd.
  2. Reproduce by running `wrangler dev` against the built worker (or `astro dev` with the adapter) and opening the same URL.
  3. Replace or guard Node-only APIs with web-standard equivalents available in workerd.
  4. Mark the failing page as server-rendered (`export const prerender = false`) if it cannot be built statically.
  5. Provide required environment variables/secrets for the build if the error mentions a missing binding or env var.

Example fix

// before — page crashes under workerd at build
import { readFileSync } from 'node:fs';
const data = JSON.parse(readFileSync('data.json', 'utf-8'));

// after — static import bundled for any runtime
import data from './data.json';
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await build({ root: './' });
} catch (e) {
  const msg = e instanceof Error ? e.message : String(e);
  const m = msg.match(/Failed to prerender (\S+): (.*)/s);
  if (m) {
    console.error(`Page ${m[1]} failed under workerd:`, m[2]);
    // mark for exclusion or fix, then re-run
    process.exitCode = 1;
  } else throw e;
}

Prevention

When it happens

Trigger: `astro build` with @astrojs/cloudflare prerendering a page whose render throws inside workerd: an uncaught exception in frontmatter, component code, or middleware for that exact request.url.

Common situations: Pages using Node-only APIs (fs, crypto internals, native modules) that work in `astro dev` but fail under workerd; a database/NPC client initialized at render time failing in the build sandbox; accessing request headers/env vars missing during build.

Related errors


AI-assisted analysis of withastro/astro@e294953aa8 (2026-09-09). Data as JSON: /api/errors/ea7fb30939f4aec3. Report an issue: GitHub.

Appendix: source

Thrown at packages/integrations/cloudflare/src/prerenderer.ts:275

				url: request.url,
				routeData: serializeRouteData(routeData, trailingSlash),
				collectMetadata,
			};

			const response = await fetch(`${serverUrl}${PRERENDER_ENDPOINT}`, {
				method: 'POST',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify(body),
				redirect: 'manual',
			});

			// Check for prerender errors surfaced by the workerd handler via header
			// (the response body may be stripped by the Vite preview server).
			// Only the header marks a failure: pages may intentionally return
			// non-2xx responses while prerendering (e.g. a custom 404 page).
			const prerenderError = response.headers.get('x-astro-prerender-error');
			if (prerenderError) {
				throw new Error(`Failed to prerender ${request.url}: ${prerenderError}`);
			}

			if (collectMetadata) {
				return readFramedPrerenderResponse(response);
			}

			return response;
		},

		collectStaticImages:
			hasBuildImageService || hasBindingImageService
				? async (): Promise<AssetsGlobalStaticImagesList> => {
						const response = await fetch(`${serverUrl}${STATIC_IMAGES_ENDPOINT}`, {
							method: 'POST',
							headers: { 'Content-Type': 'application/json' },
						});

						if (!response.ok) {

View on GitHub (pinned to e294953aa8)