Skip to content

[nextjs-tracker] Server action forwarding loop with middleware rewrites #1225

@github-actions

Description

@github-actions

Next.js change

Next.js fixed an infinite forwarding loop that occurs when middleware rewrites a Server Action POST to a page that doesn't bundle the action. The receiving worker forwards the request to a worker that has the action, but the forwarded request hits middleware again and gets rewritten, looping indefinitely until undici's headers timeout (~300s) or memory pressure brings the server down. The fix is two-part: (1) skip forwarding when the request already carries x-action-forwarded: 1, and (2) when the forwarded worker responds with x-nextjs-action-not-found: 1, propagate that header + 404 status onto the originating response so the client throws UnrecognizedActionError instead of a generic "unexpected response" error.

Commits: 20892dd4
Next.js files changed: packages/next/src/server/app-render/action-handler.ts, test/e2e/app-dir/action-forward-loop/*

Why this matters to vinext

vinext's App Router server action handling lives in packages/vinext/src/entries/app-rsc-entry.ts and packages/vinext/src/server/ (per the layering rules in AGENTS.md). If vinext implements any form of cross-worker action forwarding for Cloudflare Workers (or plans to), it inherits the same loop bug whenever middleware rewrites the action POST. Even if vinext currently single-worker-bundles all actions, the x-nextjs-action-not-found -> UnrecognizedActionError propagation is a client-contract behavior that should be matched: the client expects a 404 + x-nextjs-action-not-found: 1 header to surface as unstable_isUnrecognizedActionError, not as a generic error.

Specific things to check in vinext:

  • Server action handling in App Router production/dev paths — confirm whether a 404 from a server action POST is returned with x-nextjs-action-not-found: 1 so client error boundaries can detect it.
  • Middleware + server action POST interaction — if middleware can rewrite an action POST to a different route, confirm the request still reaches a handler that knows the action ID, and that we don't blindly forward/loop.

Priority

Minor

  • Likely a non-issue if vinext doesn't do cross-worker action forwarding today, but the client-facing UnrecognizedActionError contract is worth verifying.

Suggested action

Investigate: Confirm vinext's server action handler returns x-nextjs-action-not-found: 1 + 404 when the action ID is unknown. Add an E2E test mirroring test/e2e/app-dir/action-forward-loop — middleware that rewrites POSTs to a page without the action, a form that submits a server action wrapped in a React error boundary using unstable_isUnrecognizedActionError. If vinext implements action forwarding in the future, add the x-action-forwarded guard up front.

Metadata

Metadata

Assignees

No one assigned

    Labels

    nextjs-trackingTracking issue for a Next.js canary change relevant to vinext

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions