AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

Segment Cache Cross-URL Poisoning Under HtmlLimitedBots Catch-All Disables PPR Serving

When htmlLimitedBots is set to /.*/ and cacheComponents/partialPrefetching are enabled, RSC prefetch responses bypass the PPR shell (no x-nextjs-postponed). The client still chooses the PPR fetch strategy, stores the full concrete page under a param-blind shell vary path, and sibling prefetches overwrite each other. Soft navigation then renders the wrong sibling page (e.g., /item/alpha shows Item delta). Affects Next.js 16.3.3 production; not reproducible on 16.4.0-canary.0.

highConfidence 92%Next.jsAffected V16.3.3Fixed V16.4.0-Canary.0

Origin Analysis

In Next.js 16.3.3, the segment cache scheduler prioritizes the `SubtreeHasPartialPrefetching` hint over `route.supportsPerSegmentPrefetching`. When htmlLimitedBots matches all user agents, PPR routes bypass shell serving even for RSC prefetches, so prefetch responses contain full pages without `x-nextjs-postponed`. The client nevertheless uses FetchStrategy.PPR, and `fulfillEntrySpawnedByRuntimePrefetch` stores these responses under the tree's param-blind `shellVaryPath` (all dynamic params replaced with `Fallback`). Each subsequent sibling prefetch overwrites the same fallback entries, and later lookups resolve to whichever sibling was prefetched last, causing cross-URL cache poisoning.
1. Create a Next.js 16.3.3 app with `cacheComponents: true`, `partialPrefetching: true`, and `htmlLimitedBots: /.*/` in next.config.js. 2. Add a static page with links to /item/alpha, /item/beta, /item/charlie, /item/delta. 3. Implement app/item/[...slug]/page.js using `'use cache'` for data that feeds both page body and generateMetadata. 4. Build and start production (`next build && next start`). 5. Open `/` in a fresh browser profile and wait ~3 seconds for all link prefetches. 6. Click the alpha link; observe the URL is /item/alpha but the title and heading show Item delta or charlie (the last prefetched sibling).

Fixing Code Block

Edge Case Audit

This client-side safeguard addresses the poisoning but does not restore Instant Navigation for these routes; users may see additional full-page requests. Backporting to 16.3.x may conflict with other segment cache changes; test thoroughly with htmlLimitedBots enabled and disabled, concurrent sibling prefetches, and route transitions. Rollback advice: if this patch causes unexpected behavior, revert it and temporarily remove or narrow the htmlLimitedBots catch-all until an official fix is available. Concurrency and multi-threaded browser tabs could still race if the root cause (server bypassing PPR for RSC) is not addressed.

Ecosystem Topology