Next.js 14.2.18

RSC Cross-Version Bug Reproduction

This Next.js 14 app shares a domain with a Next.js 16 app (via Vercel rewrites). A server-side redirect() sends the user to a path served by the Next 16 app. The client router follows the redirect with an RSC fetch containing v14-format headers that Next 16 cannot parse, causing a 500 Internal Server Error.

Reproduce the Bug

Navigates to /redirect, a page component that calls redirect('/receiver/no-fix'). The server responds with a 307 to /receiver/no-fix, which is rewritten to the Next 16 app. A dummy page.tsx at /receiver/no-fix in this app registers the path in the client router's route manifest, so the client sends RSC headers ( RSC: 1, Next-Router-State-Tree) on the follow-up request. Next 16 fails to parse the v14 header format and returns a 500.

Open DevTools → Network tab before clicking. Look for the request to /receiver/no-fix — it will have RSC headers and return a 500. The client router then retries as a full page navigation (no RSC headers) and gets a 200.

Trigger Server Redirect → 500
Root cause: The Next-Router-State-Tree header schema changed between Next 14 and 16. The 5th tuple element is optional(boolean()) in v14 but optional(number()) in v16. parseAndValidateFlightRouterState() in Next 16 throws when it receives the v14 format: "The router state header was sent but could not be parsed."

Why middleware can't fix this: Next.js's adapter.js force-restores all flight headers (rsc, next-router-state-tree, etc.) after middleware returns — they are explicitly marked as "not overridable / removable." No Next.js middleware on either app can strip these headers.

Receiver URL: https://rsc-cross-version-repro-next16-rece.vercel.app