vercel/next.js · warning

Request failed (${response.status}) for ${url}

Error message

Request failed (${response.status}) for ${url}

What it means

Thrown by measureRequest (benchmark.ts:367) when a single measurement fetch returns a non-OK HTTP status. measureRequest is used in both warmup (via runSerialRequests) and the timed serial/under-load phases. In the timed phases this throw is caught locally (runSerialRequests/runConcurrentRequests count it as an error and continue), but in warmup's runSerialRequests a 100%-failure batch is later surfaced separately. The status is embedded so you can tell 500 from 404/429/etc.

Source

Thrown at bench/render-pipeline/benchmark.ts:367

// Reads the body as a stream so TTFB (first body chunk) can be observed
// separately from total latency. Byte counts are of the decompressed body.
async function measureRequest(
  url: string,
  timeoutMs: number
): Promise<RequestSample> {
  const controller = new AbortController()
  const timeout = setTimeout(() => controller.abort(), timeoutMs)

  try {
    const start = performance.now()
    const response = await fetch(url, {
      cache: 'no-store',
      signal: controller.signal,
    })
    if (!response.ok) {
      await response.arrayBuffer().catch(() => undefined)
      throw new Error(`Request failed (${response.status}) for ${url}`)
    }
    let ttfbMs = -1
    if (response.body) {
      const reader = response.body.getReader()
      while (true) {
        const { done } = await reader.read()
        if (done) break
        if (ttfbMs < 0) ttfbMs = performance.now() - start
      }
    }
    const totalMs = performance.now() - start
    if (ttfbMs < 0) ttfbMs = totalMs
    return { totalMs, ttfbMs }
  } finally {
    clearTimeout(timeout)
  }
}

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Check the post-run warnings: 'N/M requests failed' lines tell you how many; if all failed, the route is wrong or the server is broken.
  2. curl the route URL directly to see the status and response body — fix the route or the app.
  3. If failing only under load (--load-concurrency), reduce concurrency to see if it's a capacity/crash issue.
  4. Confirm the build is current and the route exists in the fixture before benchmarking.

Example fix

# before — benchmarking a non-existent route, all requests 404
#   pnpm bench:render-pipeline --routes=/missing

# after — benchmark a route the fixture actually serves
#   curl -I http://127.0.0.1:3199/dashboard   # confirm 200 first
#   pnpm bench:render-pipeline --routes=/dashboard
Defensive patterns

Strategy: try-catch

Validate before calling

// before the timed phase, confirm the route is healthy:
async function routeIsHealthy(url: string): Promise<boolean> {
  try {
    const res = await fetch(url, { signal: AbortSignal.timeout(3000) })
    return res.ok
  } catch { return false }
}
if (!(await routeIsHealthy(measureUrl))) throw new Error(`pre-flight: ${measureUrl} not healthy`)

Type guard

function isRequestStatusError(err: unknown): boolean {
  return err instanceof Error && /^Request failed \(\d{3}\) for /.test(err.message)
}

Try / catch

// In runSerialRequests/runConcurrentRequests this is ALREADY caught and counted as an error.
// If you call measureRequest directly, mirror that tolerance:
try {
  samples.push(await measureRequest(url, timeoutMs))
} catch (err) {
  if (isRequestStatusError(err)) { errors++; continue }
  throw err
}

Prevention

When it happens

Trigger: During measurement, the server returns 4xx/5xx for the benchmarked route: a route that doesn't exist (404), server error during load (500), rate limiting (429), or the server crashing under concurrency and returning errors. Each failed request throws this; the phase tallies them as errors and keeps going unless all fail.

Common situations: Benchmarking a route not present in the fixture (404); server throwing under high concurrency; the app has an unhandled error on that path; middleware returning 403; the server was measured against the wrong build.

Related errors


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