vercel/next.js · error · Error
An unexpected response was received from the server.
Error message
An unexpected response was received from the server.
What it means
Thrown at server-action-reducer.ts:226-234 when a Server Action response is neither an RSC payload (`text/x-component`) nor carries an `x-action-redirect` header. The client expects every valid action response to be Flight data or an external redirect; anything else is treated as a protocol violation and surfaced as a generic `Error` whose message is the response body if it was a `text/plain` error, otherwise this literal string.
Source
Thrown at packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts:234
: undefined
const contentType = res.headers.get('content-type')
const isRscResponse = !!(
contentType && contentType.startsWith(RSC_CONTENT_TYPE_HEADER)
)
// Handle invalid server action responses.
// A valid response must have `content-type: text/x-component`, unless it's an external redirect.
// (external redirects have an 'x-action-redirect' header, but the body is an empty 'text/plain')
if (!isRscResponse && !redirectLocation) {
// The server can respond with a text/plain error message, but we'll fallback to something generic
// if there isn't one.
const message =
res.status >= 400 && contentType === 'text/plain'
? await res.text()
: 'An unexpected response was received from the server.'
throw new Error(message)
}
let actionResult: FetchServerActionResult['actionResult']
let actionFlightData: FetchServerActionResult['actionFlightData']
let actionFlightDataRenderedSearch: FetchServerActionResult['actionFlightDataRenderedSearch']
let couldBeIntercepted: boolean = false
if (isRscResponse) {
// Server action redirect responses carry the Flight data of the redirect
// target, which may be prerendered with a completeness marker byte
// prepended. Strip it before passing to Flight.
const responsePromise = redirectLocation
? processFetch(res).then(({ response: r }) => r)
: Promise.resolve(res)
const response: ActionFlightResponse = await createFromFetch(
responsePromise,
{View on GitHub (pinned to 0ae8c72462)
Solutions
- Open the browser devtools Network tab and inspect the action POST response body and status code to identify what the server actually returned.
- Check server logs for the unhandled exception that produced an HTML error page instead of an RSC error payload.
- Verify no middleware/proxy is intercepting POSTs to the page URL and returning a non-Flight response.
- Confirm `basePath` and `assetPrefix` are correct so the action POST reaches the Next.js server.
Example fix
// before: action throws an unhandled error -> HTML error page -> generic message
'use server'
export async function action() {
throw 'oops' // non-Error throw produces an opaque server error
}
// after: throw a proper Error so the server returns a Flight error payload
'use server'
export async function action() {
throw new Error('Something went wrong')
} Defensive patterns
Strategy: try-catch
Validate before calling
// Cannot prevent from the client; validate server-side that actions // return proper Flight responses. Ensure actions throw Error subclasses // so Next.js returns RSC error payloads, not HTML error pages.
Type guard
function isLikelyFlightResponse(res: Response): boolean {
const ct = res.headers.get('content-type') ?? ''
return ct.startsWith('text/x-component')
} Try / catch
'use client'
try {
await myAction()
} catch (err) {
// err.message may be the server's text/plain body or the generic string.
console.error('Action failed:', err instanceof Error ? err.message : err)
// Show user-facing fallback UI
} Prevention
- Always throw Error subclasses inside Server Actions so Next.js returns Flight error payloads.
- Ensure no middleware/auth layer redirects action POSTs to HTML login pages.
- Monitor server logs for unhandled exceptions during action execution.
- Verify reverse proxies/CDNs pass through POST bodies and content types unchanged.
When it happens
Trigger: The server returned HTML (e.g. a 500 error page, a login redirect, a WAF challenge) instead of an RSC response; a proxy/CDN intercepted the POST and returned a non-Flight body; the action threw an unhandled server exception that Next.js rendered as an error page; the route handler returned a `Response` with the wrong content type.
Common situations: Auth middleware redirecting the action POST to a login HTML page; a reverse proxy returning a 502/HTML error page; the server crashing mid-action and returning the default error document; misconfigured `basePath`/`assetPrefix` causing the POST to hit a static host returning HTML.
Related errors
- `unstable_isUnrecognizedActionError` can only be used on the
- Not a redirect error
- Server Action "${actionId}" was not found on the server. Re
- Failed to fetch ${url}
- [inspect] ${route}: not an App Router document (no __next_f)
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/d43b172000cf97ed.
Report an issue: GitHub.