Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Fonger opened this issue Mar 8, 2025 · 1 comment
Labels
Dynamic Routes Related to dynamic routes. Redirects Related to redirecting. Route Handlers Related to Route Handlers.

Comments

@Fonger
Copy link
Contributor

Fonger commented Mar 8, 2025

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
@github-actions github-actions bot added Dynamic Routes Related to dynamic routes. Redirects Related to redirecting. Route Handlers Related to Route Handlers. labels Mar 8, 2025
@Fonger Fonger changed the title next/link RSC ?_rsc=xxxx query cache busting missing after redirects() next/link RSC ?_rsc=xxxx lead to cache pollution and leak RSC response to browser page after redirects() Mar 19, 2025
@Fonger Fonger changed the title next/link RSC ?_rsc=xxxx lead to cache pollution and leak RSC response to browser page after redirects() Missing ?_rsc=xxxx after redirects() that lead to cache pollution and leak RSC response to browser page Mar 19, 2025
@KFrysztak
Copy link

We are having almost exactly the same problem.

From what I was able to trace in my case most likely NextResponse.redirect() is stripping _rsc. This is causing cache separation problems for cdn.

The final outcome is what @Fonger described, browser is getting RSC is served instead of HTML.

We are on [email protected]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Dynamic Routes Related to dynamic routes. Redirects Related to redirecting. Route Handlers Related to Route Handlers.
Projects
None yet
Development

No branches or pull requests

2 participants