withastro/astro · error · AstroError

PrerenderClientAddressNotAvailable

PrerenderClientAddressNotAvailable

Error message

`Astro.clientAddress` cannot be used inside prerendered route ${name}.

What it means

Thrown by Astro.clientAddress getter when the current route is prerendered (static) at build time. Prerendered pages run at build with no real HTTP request, so there is no client IP to read. The check is routeData.prerender being true inside getClientAddress().

Source

Thrown at packages/astro/src/core/fetch/fetch-state.ts:592

					},
					error(msg: string) {
						pipeline.logger.error(null, msg);
					},
				};
			},
		};

		this.defineProviderGetters(partial);

		return partial as Omit<AstroGlobal, 'props' | 'self' | 'slots'>;
	}

	getClientAddress(): string {
		const { pipeline, clientAddress } = this;
		const routeData = this.routeData!;

		if (routeData.prerender) {
			throw new AstroError({
				...AstroErrorData.PrerenderClientAddressNotAvailable,
				message: AstroErrorData.PrerenderClientAddressNotAvailable.message(routeData.component),
			});
		}

		if (clientAddress) {
			return clientAddress;
		}

		if (pipeline.adapterName) {
			throw new AstroError({
				...AstroErrorData.ClientAddressNotAvailable,
				message: AstroErrorData.ClientAddressNotAvailable.message(pipeline.adapterName),
			});
		}

		throw new AstroError(AstroErrorData.StaticClientAddressNotAvailable);
	}

View on GitHub (pinned to d081033d5f)

Solutions

  1. Remove `export const prerender = true` from the page (or set output: 'server') so the route is server-rendered.
  2. Guard access: only read Astro.clientAddress when the route is on-demand, e.g. wrap in a check or move the IP-dependent code to a server-rendered endpoint.
  3. If the page must be prerendered, capture the client address at runtime via a separate server-rendered API route or adapter middleware and pass it in.

Example fix

// before
export const prerender = true;
const ip = Astro.clientAddress;

// after
export const prerender = false;
const ip = Astro.clientAddress;
Defensive patterns

Strategy: validation

Validate before calling

// Only read clientAddress on server-rendered routes.
const prerender =
  (Astro as any).routeData?.prerender ??
  (import.meta as any).env?.PRERENDER === true;
const ip = !prerender ? Astro.clientAddress : undefined;

Type guard

function isServerRendered(routeData: { prerender?: boolean } | undefined): boolean {
  return routeData?.prerender !== true;
}

Try / catch

let ip: string | undefined;
try {
  ip = Astro.clientAddress;
} catch (e) {
  if (e instanceof Error && /prerendered route/i.test(e.message)) {
    ip = undefined; // expected on prerendered pages
  } else throw e;
}

Prevention

When it happens

Trigger: Accessing Astro.clientAddress inside a .astro page or endpoint that has `export const prerender = true`, or a route that became prerendered because output is 'static'. The getter on the page-level Astro global calls state.getClientAddress(), which throws when routeData.prerender is true.

Common situations: Adding prerender = true to a page that logs or analytics-tracks visitor IPs; switching a project from output 'server' to 'static' and forgetting to remove clientAddress usage; reading clientAddress in a shared component imported by a prerendered page.

Related errors


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