Skip to content

Missing ?_rsc=xxxx after redirects() that lead to cache pollution and leak RSC response to browser page #76925

Closed
@Fonger

Description

@Fonger

Link to the code that reproduces this issue

https://codesandbox.io/p/devbox/next-js-rsc-cache-busting-redirect-not-working-5psn4k

To Reproduce

  1. Open the homepage of this repro sandbox.

The next.config.js file is configured as

import type { NextConfig } from "next";
const nextConfig: NextConfig = {
  reactStrictMode: true,
  async redirects() {
    return [
      {
        source: "/fake-path",
        destination: "/real-path",
        permanent: true,
      },
    ];
  },
};
export default nextConfig;
  1. Click "Go to Fake Path." This triggers a redirect from /fake-path to /real-path.
  2. Observe that the ?_rsc query parameter is missing in the redirected request.

fetch /fake-path?_rsc=xxx and 308 to /real-path without query
Image

Following the redirect, fetch /real-path again, it's text/x-component RSC response but there's no ?_rsc=xxx query busting. This make local browser or some CDN providers hard to distinguish "HTML Web Page" and "RSC Component Response".

I can confirm this can happen to browser in bf cache.
Image

Current vs. Expected behavior

Current
308 Redirected RSC requests ?_rsc=xxx doesn't forward.

Expected
308 Redirected RSC request should also contain ?_rsc=xxx query to help Browser / CDN to separate cache.

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #1 SMP PREEMPT_DYNAMIC Sun Aug  6 20:05:33 UTC 2023
  Available memory (MB): 4242
  Available CPU cores: 2
Binaries:
  Node: 20.9.0
  npm: 9.8.1
  Yarn: 1.22.19
  pnpm: 8.10.2
Relevant Packages:
  next: 15.2.2-canary.4 // Latest available version is detected (15.2.2-canary.4).
  eslint-config-next: N/A
  react: 19.0.0
  react-dom: 19.0.0
  typescript: 5.3.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Dynamic Routes, Redirects, Route Handlers

Which stage(s) are affected? (Select all that apply)

next dev (local), next start (local), Other (Deployed), Vercel (Deployed), next build (local)

Additional context

Suspected Cause

I suspect this issue was introduced in #51195

It seems that the following code is intended to remove the ?_rsc query parameter when redirecting to a page router. However, in this case, the target destination is an app router, meaning the ?_rsc query should not have been removed.

Real-world Impact

This issue has also been observed on Cursor’s official website.

As shown below, the "200 OK (from disk cache)" response indicates that the browser is caching and serving an RSC response instead of a normal HTML page. While the browser correctly renders the cached content as-is, the problem arises because RSC responses are not meant to be directly presented to users. Without the proper client-side cache separation, users end up seeing raw, incomprehensible RSC data rather than a functional UI in html.

Expected behavior:
✅ The page should be rendered as a normal HTML document.

Actual behavior:
❌ The browser caches and serves an RSC response instead of HTML.

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    Dynamic RoutesRelated to dynamic routes.RedirectsRelated to redirecting.Route HandlersRelated to Route Handlers.linear: nextConfirmed issue that is tracked by the Next.js team.locked

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions