nextjs - ✅(Solved) Fix notFound breaks Suspense in layout with cacheComponents enabled [2 pull requests, 6 comments, 6 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#86251Fetched 2026-04-08 02:11:51
View on GitHub
Comments
6
Participants
6
Timeline
35
Reactions
10
Author
Assignees
Timeline (top)
subscribed ×7commented ×6referenced ×6cross-referenced ×4

Error Message

  1. you see Application error: a client-side exception has occurred while loading localhost (see the browser console for more information). Console shows Uncaught Error: Connection closed.

Fix Action

Fixed

PR fix notes

PR #87041: fix: handle notFound in Suspense with cacheComponents enabled

Description (problem / solution / changelog)

What?

This PR fixes an issue where notFound() (and other HTTP access fallback errors like forbidden()/unauthorized()) would cause "Connection closed" errors when cacheComponents: true is enabled and the page has a Suspense boundary with an async component.

Why?

When cacheComponents is enabled and a page is prerendered, subsequent requests use DynamicState.DATA mode which only sends RSC data without re-rendering the HTML shell. However, when notFound() is thrown during this RSC render, the prerendered HTML doesn't contain the not-found component, causing the client to receive an incomplete stream and display "Connection closed" errors.

How?

This fix buffers the RSC stream in DynamicState.DATA mode to detect HTTP access fallback errors. After consuming the stream:

  1. Check reactServerErrorsByDigest for any errors with the HTTP_ERROR_FALLBACK_ERROR_CODE prefix
  2. If no such errors exist, send the buffered RSC data as before
  3. If such errors are found, set the appropriate status code and fall through to the full dynamic render path which properly handles the not-found page

Test Plan

Added two test cases:

  • not-found-suspense: Tests notFound() thrown inside a Suspense boundary
  • not-found-with-layout-suspense: Exact reproduction of the issue - notFound() in page with async component in layout's Suspense

Fixes #86251

Changed files

  • packages/next/src/server/app-render/app-render.tsx (modified, +70/-11)
  • packages/next/src/server/app-render/create-error-handler.tsx (modified, +10/-0)
  • test/e2e/app-dir/cache-components/app/cases/not-found-suspense/not-found.tsx (added, +10/-0)
  • test/e2e/app-dir/cache-components/app/cases/not-found-suspense/page.tsx (added, +35/-0)
  • test/e2e/app-dir/cache-components/app/cases/not-found-with-layout-suspense/layout.tsx (added, +28/-0)
  • test/e2e/app-dir/cache-components/app/cases/not-found-with-layout-suspense/not-found.tsx (added, +10/-0)
  • test/e2e/app-dir/cache-components/app/cases/not-found-with-layout-suspense/page.tsx (added, +5/-0)
  • test/e2e/app-dir/cache-components/cache-components.test.ts (modified, +50/-0)

PR #88444: fix(rsc): handle router errors gracefully in flight response stream

Description (problem / solution / changelog)

What?

When notFound(), redirect(), forbidden(), or unauthorized() is called inside a Suspense boundary with cache components enabled, the page would fail with "Connection closed" errors instead of properly rendering the not-found/error page.

Why?

The flight response stream was calling controller.error(error) for all caught errors, including Next.js router errors. This would abort the stream before the serialized error data could reach the client, preventing error boundaries from handling them properly.

How?

Check if the caught error is a Next.js router error using isNextRouterError(). If so, close the stream gracefully with controller.close() instead of erroring, allowing the serialized error data to reach the client where error boundaries can handle them.

Fixes #86251

NAR-711

Changed files

  • packages/next/src/client/components/http-access-fallback/http-access-fallback.ts (modified, +6/-0)
  • packages/next/src/server/app-render/app-render.tsx (modified, +65/-14)
  • packages/next/src/server/app-render/create-component-tree.tsx (modified, +76/-19)
  • test/e2e/app-dir/cache-components/app/cases/forbidden-with-layout-suspense/forbidden.tsx (added, +10/-0)
  • test/e2e/app-dir/cache-components/app/cases/forbidden-with-layout-suspense/layout.tsx (added, +28/-0)
  • test/e2e/app-dir/cache-components/app/cases/forbidden-with-layout-suspense/page.tsx (added, +7/-0)
  • test/e2e/app-dir/cache-components/app/cases/not-found-suspense/not-found.tsx (added, +10/-0)
  • test/e2e/app-dir/cache-components/app/cases/not-found-suspense/page.tsx (added, +35/-0)
  • test/e2e/app-dir/cache-components/app/cases/not-found-with-layout-suspense/layout.tsx (added, +28/-0)
  • test/e2e/app-dir/cache-components/app/cases/not-found-with-layout-suspense/not-found.tsx (added, +10/-0)
  • test/e2e/app-dir/cache-components/app/cases/not-found-with-layout-suspense/page.tsx (added, +7/-0)
  • test/e2e/app-dir/cache-components/app/cases/unauthorized-with-layout-suspense/layout.tsx (added, +28/-0)
  • test/e2e/app-dir/cache-components/app/cases/unauthorized-with-layout-suspense/page.tsx (added, +7/-0)
  • test/e2e/app-dir/cache-components/app/cases/unauthorized-with-layout-suspense/unauthorized.tsx (added, +10/-0)
  • test/e2e/app-dir/cache-components/cache-components.test.ts (modified, +99/-0)
  • test/e2e/app-dir/cache-components/next.config.js (modified, +1/-0)

Code Example

Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 10 Pro
  Available memory (MB): 32457
  Available CPU cores: 12
Binaries:
  Node: 20.18.2
  npm: 10.8.2
  Yarn: 1.22.22
  pnpm: 10.18.3
Relevant Packages:
  next: 16.0.3 // Latest available version is detected (16.0.3).
  eslint-config-next: N/A
  react: 19.2.0
  react-dom: 19.2.0
  typescript: 5.9.3
Next.js Config:
  output: N/A
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

https://github.com/ottetz/next-not-found-issue

To Reproduce

  1. pnpm build
  2. pnpm start
  3. open http://localhost:3000
  4. you see Application error: a client-side exception has occurred while loading localhost (see the browser console for more information). Console shows Uncaught Error: Connection closed.

Current vs. Expected behavior

Running app in dev mode corretly shows not found stub and Fetched Data from suspended component

<img width="516" height="162" alt="Image" src="https://github.com/user-attachments/assets/2cfa09d1-451b-43e1-8804-9c19a2298cf1" />

Expected built app to do the same

Provide environment information

Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 10 Pro
  Available memory (MB): 32457
  Available CPU cores: 12
Binaries:
  Node: 20.18.2
  npm: 10.8.2
  Yarn: 1.22.22
  pnpm: 10.18.3
Relevant Packages:
  next: 16.0.3 // Latest available version is detected (16.0.3).
  eslint-config-next: N/A
  react: 19.2.0
  react-dom: 19.2.0
  typescript: 5.9.3
Next.js Config:
  output: N/A

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

cacheComponents, Loading UI and Streaming, Not Found

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

next build (local), Vercel (Deployed)

Additional context

cacheComponents: true is required in next.config.js to reproduce

extent analysis

TL;DR

  • The issue may be resolved by adjusting the next.config.js file, specifically the cacheComponents setting or exploring alternative configurations for the output property.

Guidance

  • Review the next.config.js file to ensure that the cacheComponents setting is properly configured, as this is required to reproduce the issue.
  • Investigate the impact of setting cacheComponents to false or exploring other configuration options for output in next.config.js.
  • Verify that the issue persists when running the application in development mode versus production mode, as the expected behavior is observed in development mode.
  • Check the browser console for more detailed error information related to the Uncaught Error: Connection closed message.

Example

  • No specific code example is provided due to the lack of explicit code snippets in the issue description.

Notes

  • The issue seems to be related to the interaction between next version 16.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

nextjs - ✅(Solved) Fix notFound breaks Suspense in layout with cacheComponents enabled [2 pull requests, 6 comments, 6 participants]