withastro/astro · warning

${url.pathname} ${colors.bold(method)} requests are not avai

Error message

${url.pathname} ${colors.bold(method)} requests are not available in static endpoints. Mark this page as server-rendered (`export const prerender = false;`) or update your config to `output: 'server'` to make all your pages server-rendered by default.

What it means

Astro endpoints render by matching the uppercase request method against exported handlers (GET, POST, ALL). When a route is prerendered to static files, only GET and HEAD can ever be served; the runtime checks isPrerendered && !['GET','HEAD'].includes(method) and logs this router warning telling you the route must be server-rendered for other verbs.

Source

Thrown at packages/astro/src/runtime/server/endpoint.ts:30

	mod: {
		[method: string]: APIRoute;
	},
	context: APIContext,
	isPrerendered: boolean,
	logger: AstroLogger,
	state?: FetchState,
) {
	const { request, url } = context;

	const method = request.method.toUpperCase();
	// use the exact match on `method`, fall back to ALL
	let handler = mod[method] ?? mod['ALL'];
	// use GET handler for HEAD requests
	if (!handler && method === 'HEAD' && mod['GET']) {
		handler = mod['GET'];
	}
	if (isPrerendered && !['GET', 'HEAD'].includes(method)) {
		logger.warn(
			'router',
			`${url.pathname} ${colors.bold(
				method,
			)} requests are not available in static endpoints. Mark this page as server-rendered (\`export const prerender = false;\`) or update your config to \`output: 'server'\` to make all your pages server-rendered by default.`,
		);
	}
	if (handler === undefined) {
		logger.warn(
			'router',
			`No API Route handler exists for the method "${method}" for the route "${url.pathname}".\n` +
				`Found handlers: ${Object.keys(mod)
					.map((exp) => JSON.stringify(exp))
					.join(', ')}\n` +
				('all' in mod
					? `One of the exported handlers is "all" (lowercase), did you mean to export 'ALL'?\n`
					: ''),
		);
		// No handler matching the verb found, so this should be a

View on GitHub (pinned to 52e6c34790)

Solutions

  1. Add `export const prerender = false;` to the endpoint file so its handlers run on the server
  2. Set output: 'server' in astro.config.mjs if most of the site should be dynamic
  3. If the endpoint is meant to be static, restrict it to GET/HEAD and remove the other verb handlers

Example fix

// before  src/pages/api/subscribe.ts (project default is static)
export const POST: APIRoute = async ({ request }) => new Response('ok');

// after
export const prerender = false;
export const POST: APIRoute = async ({ request }) => new Response('ok');
Defensive patterns

Strategy: validation

Validate before calling

// Shared endpoint guard: reject writes deterministically when the route is prerendered
export const ALL: APIRoute = ({ request }) => {
  if (import.meta.env.PRERENDER && !['GET', 'HEAD'].includes(request.method)) {
    return new Response('Method Not Allowed', { status: 405 });
  }
  // ... dispatch by method
};

Prevention

When it happens

Trigger: A request with a method other than GET/HEAD (POST, PUT, DELETE, OPTIONS, ...) hitting an endpoint that has `export const prerender = true`, or any endpoint under output: 'static' — observable in the dev server, or whenever the static output is served behind something that forwards the request instead of rejecting it.

Common situations: A newsletter/contact POST handler on a mostly-static site; switching output: 'server' to 'static' and forgetting to flip one endpoint to prerender = false; testing endpoints with curl -X POST against a static build or the dev server.

Related errors


AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18). Data as JSON: /api/errors/2b283be9814cc024. Report an issue: GitHub.