withastro/astro · error · Error

Failed to get static images from the Cloudflare prerender se

Error message

Failed to get static images from the Cloudflare prerender server (${response.status}: ${response.statusText}).${details}

What it means

Thrown by the Cloudflare prerenderer when collecting build-time-optimized static images: the POST to the `STATIC_IMAGES_ENDPOINT` on the local workerd server returns non-OK. Only active when a build-time image service is configured (`compile`, `custom`, or `cloudflare-binding` build service). The response body is appended as `details`.

Source

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

				});
				return { response: reconstructed, metadata: envelope.metadata };
			}

			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) {
							const body = await response.text();
							const details = body ? `\n${body}` : '';
							throw new Error(
								`Failed to get static images from the Cloudflare prerender server (${response.status}: ${response.statusText}).${details}`,
							);
						}

						const entries: StaticImagesResponse = await response.json();

						// Transforms left in this map fall through to the Node-side image
						// service (the user-configured service, or Sharp).
						const staticImages: AssetsGlobalStaticImagesList = new Map();
						const deferToNodeImageService = (
							entry: SerializedStaticImageEntry,
							t: SerializedStaticImageEntry['transforms'][number],
						) => {
							let existing = staticImages.get(entry.originalPath);
							if (!existing) {
								existing = { originalSrcPath: entry.originalSrcPath, transforms: new Map() };
								staticImages.set(entry.originalPath, existing);
							}

View on GitHub (pinned to d081033d5f)

Solutions

  1. Read the `details` body for the workerd image-service error.
  2. Verify the Cloudflare Images binding is configured (`images: { binding: 'MY_IMAGES' }`) and available locally.
  3. If you do not need build-time transforms, switch `imageService` to a runtime-only or Node-compatible service (e.g. sharp) to bypass this code path.
  4. Audit `<Image>` usages for invalid transform parameters.

Example fix

// before — build-time images without binding
export default defineConfig({
  adapter: cloudflare({ imageService: 'cloudflare-binding' }),
});

// after — provide the binding or use passthrough
export default defineConfig({
  adapter: cloudflare({ imageService: 'passthrough' }),
});
Defensive patterns

Strategy: validation

Validate before calling

// Before enabling build-time images, confirm the Images binding:
// wrangler.jsonc must declare images.binding matching the adapter config.
const wrangler = require('./wrangler.jsonc');
if (!wrangler.images?.binding) {
  throw new Error('Configure images.binding before using cloudflare-binding imageService');
}

Try / catch

try {
  await build();
} catch (e) {
  if (/Failed to get static images/.test(e.message)) {
    // details body has workerd image error; fall back to passthrough/sharp imageService
  }
  throw e;
}

Prevention

When it happens

Trigger: During build with build-time image optimization enabled, `collectStaticImages` POSTs to the workerd server and the response is not OK. Causes: workerd image handler crash, missing Cloudflare Images binding, or an invalid transform encountered during static image collection.

Common situations: Configuring `imageService` as `cloudflare-binding` for build-time transforms without a real Images binding locally. A malformed `<Image>` component config (invalid width/height/format). workerd image service version mismatch.

Related errors


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/77ed56131ad5e1f7. Report an issue: GitHub.