withastro/astro · warning

This project contains server-rendered routes, but no adapter

Error message

This project contains server-rendered routes, but no adapter is installed. This is fine for development, but an adapter will be required to build your site for production.

What it means

The project's build output is server (SSR routes present) but no adapter is configured. The dev server can serve these routes fine; producing a deployable production build requires an adapter that emits the server entrypoint. The warning is printed once per process (module-level hasWarnedMissingAdapter flag).

Source

Thrown at packages/astro/src/core/dev/adapter-validation.ts:12

import { getAdapterStaticRecommendation } from '../../integrations/features-validation.js';
import type { AstroSettings } from '../../types/astro.js';
import type { AstroAdapter } from '../../types/public/integrations.js';
import { AstroError, AstroErrorData } from '../errors/index.js';
import type { AstroLogger } from '../logger/core.js';

let hasWarnedMissingAdapter = false;

export function warnMissingAdapter(logger: AstroLogger, settings: AstroSettings) {
	if (hasWarnedMissingAdapter) return;
	if (settings.buildOutput === 'server' && !settings.config.adapter) {
		logger.warn(
			'config',
			'This project contains server-rendered routes, but no adapter is installed. This is fine for development, but an adapter will be required to build your site for production.',
		);
		hasWarnedMissingAdapter = true;
	}
}

export function validateSetAdapter(
	logger: AstroLogger,
	settings: AstroSettings,
	adapter: AstroAdapter,
	maybeConflictingIntegration: string,
	command?: 'dev' | 'build' | string,
) {
	if (settings.adapter && settings.adapter.name !== adapter.name) {
		throw new Error(
			`Integration "${maybeConflictingIntegration}" conflicts with "${settings.adapter.name}". You can only configure one deployment integration.`,
		);

View on GitHub (pinned to 52e6c34790)

Solutions

  1. Install and register an adapter matching your host, e.g. @astrojs/node, @astrojs/vercel, @astrojs/cloudflare
  2. Or make the site fully static (prerender all pages / output: 'static') if server rendering is not needed

Example fix

// before — astro.config.mjs
export default defineConfig({ output: 'server' });

// after
import node from '@astrojs/node';
export default defineConfig({
  output: 'server',
  adapter: node({ mode: 'standalone' }),
});
Defensive patterns

Strategy: validation

Validate before calling

// fail production CI when SSR output has no adapter
import config from './astro.config.mjs';
if (!config.adapter && (config.output === 'server' || config.output === 'hybrid')) {
  throw new Error('SSR build requires an adapter');
}

Prevention

When it happens

Trigger: settings.buildOutput === 'server' (output: 'server', or prerender = false pages) while astro.config has no `adapter` entry — checked when running `astro dev`.

Common situations: Starting an SSR project before choosing a deploy target; temporarily removing the adapter while refactoring; scaffolding templates that default to server output.

Related errors


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