withastro/astro · warning

[astro:cache] Skipping cache for ${url.pathname}${url.search

Error message

[astro:cache] Skipping cache for ${url.pathname}${url.search} because response includes Set-Cookie.

What it means

The built-in memory cache provider never stores a response that carries a Set-Cookie header, because replaying a cached Set-Cookie would leak one visitor's cookies to other visitors. When a response entering the cache sets a cookie, warnSkippedSetCookie() prints this warning and that response is simply not written to the cache.

Source

Thrown at packages/astro/src/core/cache/memory-provider.ts:270

	if (!entry.vary || !entry.varyValues) return true;
	for (const header of entry.vary) {
		const requestValue = request.headers.get(header) ?? '';
		if (requestValue !== entry.varyValues[header]) return false;
	}
	return true;
}

function hasAtLeastOneCookie(cookies: AstroCookies | undefined): boolean {
	return cookies ? !cookies.headers().next().done : false;
}

function hasSetCookieHeader(response: Response): boolean {
	if (response.headers.has('set-cookie')) return true;
	return hasAtLeastOneCookie(getCookiesFromResponse(response));
}

function warnSkippedSetCookie(url: URL): void {
	console.warn(
		`[astro:cache] Skipping cache for ${url.pathname}${url.search} because response includes Set-Cookie.`,
	);
}

/**
 * Simple LRU cache backed by a Map (insertion-order iteration).
 * When the cache exceeds `max` entries, the oldest entry is evicted.
 */
class LRUMap<K, V> {
	#map = new Map<K, V>();
	#max: number;

	constructor(max: number) {
		this.#max = max;
	}

	get(key: K): V | undefined {
		const value = this.#map.get(key);

View on GitHub (pinned to 3578d45d34)

Solutions

  1. Narrow routeRules so cookie-setting routes are not covered (e.g. give /login or /set-theme maxAge: 0 or no rule)
  2. Move cookie assignment into a non-cached endpoint or middleware outside the cached path
  3. Accept the warning if per-user personalization is intentional — such responses are always cache misses by design

Example fix

// before — astro.config.mjs: cookie route matched by the broad cache rule
export default defineConfig({
  cache: { provider: { entrypoint: 'astro/cache/memory' } },
  routeRules: { '/**': { swr: 600 } }, // also caches /set-theme
});

// after — exclude the cookie-setting route
export default defineConfig({
  cache: { provider: { entrypoint: 'astro/cache/memory' } },
  routeRules: {
    '/set-theme': { maxAge: 0 },
    '/**': { swr: 600 },
  },
});
Defensive patterns

Strategy: validation

Validate before calling

// when caching manually, only store cookie-free responses
const response = await next();
const cacheable = !response.headers.has('set-cookie');
if (cacheable) {
  // safe to cache
}

Prevention

When it happens

Trigger: A route covered by `routeRules` caching (maxAge/swr) or by cache.set() calls whose final response includes Set-Cookie — set via Astro.cookies.set(), context.cookies.set(), or middleware attaching a cookie before the response is stored.

Common situations: Caching pages that also do A/B tests, theme switching, or consent-cookie assignment; login or locale-detection routes accidentally matched by a broad '/**' routeRules pattern.

Related errors


AI-assisted analysis of withastro/astro@3578d45d34 (2026-08-18). Data as JSON: /api/errors/001c36fa82f8e2fe. Report an issue: GitHub.