vercel/next.js · error · Error

Proxy request failed: ${resp.status}

Error message

Proxy request failed: ${resp.status}

What it means

Thrown by the experimental testmode fetch interceptor when the local proxy server (running on proxyPort during `next dev`/test) returns a non-2xx status for the proxied fetch request. The testmode routes every fetch through a proxy so tests can mock responses; a failing proxy response means the test harness itself is misbehaving or rejected the request envelope.

Source

Thrown at packages/next/src/experimental/testmode/fetch.ts:115

  const resp = await originalFetch(`http://localhost:${proxyPort}`, {
    method: 'POST',
    body: JSON.stringify(proxyRequest),
    // The header lets the ClientRequest interception in `httpget.ts` identify
    // this request as part of the test proxy protocol. @mswjs/interceptors
    // intercepts at the TCP level, so this request would otherwise be
    // intercepted again when it's sent from within an interception listener,
    // recursing indefinitely.
    headers: {
      'next-test-internal': '1',
    },
    next: {
      // @ts-ignore
      internal: true,
    },
  })
  if (!resp.ok) {
    throw new Error(`Proxy request failed: ${resp.status}`)
  }

  const proxyResponse = (await resp.json()) as ProxyResponse
  const { api } = proxyResponse
  switch (api) {
    case 'continue':
      return originalFetch(request)
    case 'abort':
    case 'unhandled':
      throw new Error(
        `Proxy request aborted [${request.method} ${request.url}]`
      )
    case 'fetch':
      return buildResponse(proxyResponse)
    default:
      return api satisfies never
  }
}

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Verify the test proxy is running and listening on proxyPort; restart the dev/test server if it crashed.
  2. Inspect the proxy server logs for the failing request and fix the underlying handler that returned the error status.
  3. Confirm experimental.testmode is fully configured with a valid testApiHandler/httpMockHandler in next.config.js.
  4. Bypass the proxy for unrelated fetches by marking them with `next: { internal: true }` if they should passthrough.

Example fix

// before — mock handler throws, proxy returns 500
async function handler(req) {
  return Response.json(JSON.parse(badJson)) // throws
}
// after — guard the handler
async function handler(req) {
  try {
    return Response.json(JSON.parse(badJson))
  } catch {
    return new Response('bad input', { status: 400 })
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Before relying on the proxy, health-check it
async function proxyAlive(port: number): Promise<boolean> {
  try {
    const r = await fetch(`http://localhost:${port}`, { method: 'HEAD' })
    return r.ok || r.status === 405 // some servers reject HEAD
  } catch { return false }
}

Try / catch

try {
  return await handleFetch(originalFetch, request)
} catch (e) {
  if (/Proxy request failed/.test(e.message)) {
    // surface the failing request, optionally fall back to originalFetch(request)
    console.error('testmode proxy failed for', request.url)
  }
  throw e
}

Prevention

When it happens

Trigger: Triggered inside Next.js's experimental.testmode when a server component calls fetch(), the interceptor forwards it to the test proxy at localhost:proxyPort, and resp.ok is false. The proxy server crashed, returned 500, or the request body/headers were malformed.

Common situations: The test proxy process died or was not started; a mock handler in the test threw an exception causing a 500; mismatched Next.js versions between the test harness and the framework; or a port conflict on the proxy port. Also seen when testmode is partially configured (configuration set but no httpMockHandler registered).

Related errors


AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06). Data as JSON: /api/errors/a9417e32a4af6229. Report an issue: GitHub.