Web Development

Next.js API behind Vercel Edge intermittently returns 403 due to cached edge responses dropping Cookie headers

Environment

Environment

Next.js 13.4 app using App Router and edge functions deployed to Vercel Edge. Sessions are cookie-based (HttpOnly session cookie). App serves both SSR pages and API routes; caching rules include a CDN-level cache with default TTL and some routes use revalidate headers.

Symptoms

Symptoms

Some authenticated users intermittently receive 403s from API routes that validate the session cookie. Affected requests are random across users and appear only when requests are served from Vercel's Edge (regional cache). Switching the function to a Node serverless regionally-hosted function eliminates the 403s. Clearing the browser cache or waiting a few minutes sometimes resolves the problem for a user.

Observations

Observations

Vercel edge logs show requests served from edge cache without a Cookie header forwarded to the origin in several 403 cases. When a 403 occurs, timestamped logs from the origin show no Cookie present. Requests that hit origin directly (cache-miss) show a Cookie header. The app uses Cache-Control: s-maxage=60 on some pages and differing cache profiles for API and SSR routes. No app code is actively removing cookies before forwarding.

Already attempted

Already attempted

Disabled edge caching for the API routes (set cache-control: no-store) — problem disappeared for those routes. Attempted to set Vary: Cookie header and changed Cache-Control to private on SSR pages, but intermittent 403s still observed on mixed routes. Added custom cache keys in Vercel config for some endpoints (no consistent fix). Rewrote auth to use Authorization bearer tokens — immediate fix but required client-side changes.

Question

Question

How should Next.js and Vercel be configured so edge caching does not cause cookie-stripping or stale cached responses for routes that require cookie-based authentication? What configuration is safest and lowest-effort to ensure edge nodes forward Cookie headers (or avoid caching) without exposing private data to the CDN?

COMMUNITY RESPONSES

Verified community troubleshooting

0 replies

No answers yet..

Showing 0 of 0 community responses
AI DIAGNOSTICS

Incident analysis

Updated 1w ago• Trouble ID

Most likely causes

Edge node caches responses that should be private because Cache-Control/Vary headers don't instruct the CDN to vary by Cookie. 90%
Misconfigured route-level caching (e.g., SSR pages set to s-maxage) causing private content to be cached and served without authentication context. 85%
Vercel's default caching at the edge strips or ignores Cookie headers to maximize cache hit rate unless explicitly configured. 75%

Summary

Edge caches typically do not consider Cookie by default when caching; if a cached response is returned from edge without the Cookie forwarded, origin logic may be bypassed or see missing auth headers, causing 403. The root causes are likely a combination of cache-control directives that allow edge caching of responses that should be private, and the CDN serving cached responses without varying on Cookie. Changing caching to private or disabling edge caching for auth-protected endpoints ensures Cookie is always sent to origin or prevents caching of sensitive responses.

Suggested Fixes

Diagnostic step 1
Mark sensitive endpoints with Cache-Control: private or no-store to prevent edge caching of authenticated responses; use s-maxage only for truly public assets.
Diagnostic step 2
Send Vary: Cookie on responses that may legitimately vary by session so caches consider Cookie in the cache key (note: this can reduce cache efficiency and may still require CDN support).
Diagnostic step 3
Prefer serverless/regional functions for authenticated API logic that must always see full cookies rather than edge functions, or move session tokens to an Authorization header for stateless verification if feasible.