withastro/astro · error · AstroError

PrerenderClientAddressNotAvailable

PrerenderClientAddressNotAvailable

Error message

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

What it means

FetchState.getClientAddress() checks routeData.prerender first and throws AstroErrorData.PrerenderClientAddressNotAvailable for prerendered routes. A prerendered route renders at build time, when no live request or client socket exists, so a client IP is conceptually unavailable — even when an adapter normally supplies one for server routes.

Solutions

  1. Remove `export const prerender = true` from that route so it renders on demand
  2. Move the IP-dependent logic (logging, geolocation, rate limiting) into a server endpoint or API route that is never prerendered
  3. Guard the access so static and dynamic pages can share the component: only read clientAddress when not prerendered

Example fix

// before
const ip = Astro.clientAddress;

// after
const ip = Astro.isPrerendered ? null : Astro.clientAddress;
Defensive patterns

Strategy: validation

Validate before calling

const ip = import.meta.env.SSR && !Astro.isPrerendered ? Astro.clientAddress : null;
if (ip === null) {
  // skip IP-dependent work on prerendered pages
}

Prevention

When it happens

Trigger: Astro.clientAddress is accessed on a page that exports `const prerender = true` (or inherits prerendering from `output: 'static'`), including access from a shared component used by that page.

Common situations: Marking marketing pages prerendered for performance while they still log visitor IPs; migrating an app from SSR to hybrid/static output; a shared analytics component using Astro.clientAddress being added to a static page.

Related errors


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

Appendix: source

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

			get csp() {
				return state.getCsp();
			},
			get logger(): APIContext['logger'] {
				return astroToRuntimeLogger(logger);
			},
		};

		this.defineProviderGetters(partial);

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

	getClientAddress(): string {
		const { 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 (this.manifest.adapterName) {
			throw new AstroError({
				...AstroErrorData.ClientAddressNotAvailable,
				message: AstroErrorData.ClientAddressNotAvailable.message(this.manifest.adapterName),
			});
		}

		throw new AstroError(AstroErrorData.StaticClientAddressNotAvailable);
	}

View on GitHub (pinned to e294953aa8)