vercel/next.js · error
Server did not become ready within ${timeoutMs}ms
Error message
Server did not become ready within ${timeoutMs}ms What it means
Thrown by waitForServerReady (benchmark.ts:321) when the readiness loop exhausts timeoutMs (default 30000 via --timeout-ms) without the server returning response.ok, and crucially without the child having exited (that's error [14]). So the process is alive but never served a healthy 200 — it's hung in boot, slow to compile, or stuck returning non-2xx/non-5xx (e.g. endless redirects) that never satisfy response.ok.
Source
Thrown at bench/render-pipeline/benchmark.ts:321
// Without this check, a server that dies on startup (e.g. EADDRINUSE
// against a stale server on the same port) is indistinguishable from
// a slow one — worse, a 200 from whatever else owns the port would
// pass, and the run would silently measure the wrong server.
if (serverDied?.()) {
throw new Error(
`Server process exited before becoming ready (is port already in use?)`
)
}
try {
const response = await fetch(url, { cache: 'no-store' })
await response.arrayBuffer()
if (response.ok) return
} catch {
// server not ready yet
}
await sleep(200)
}
throw new Error(`Server did not become ready within ${timeoutMs}ms`)
}
function spawnedServerDied(server: ReturnType<typeof spawn>): () => boolean {
return () => server.exitCode !== null || server.signalCode !== null
}
// The death check alone is racy on a contested port: a stale server can
// answer the readiness probe before our child fails to bind, and the run
// would silently measure the wrong server.
async function assertPortFree(port: number): Promise<void> {
const controller = new AbortController()
const timeout = setTimeout(() => controller.abort(), 1000)
try {
await fetch(`http://127.0.0.1:${port}/`, {
cache: 'no-store',
signal: controller.signal,
})
} catch {View on GitHub (pinned to 0ae8c72462)
Solutions
- Raise --timeout-ms if boot is legitimately slow (e.g. --timeout-ms=120000).
- Ensure the first route in --routes exists and returns 200 — the readiness probe uses routes[0] (benchmark.ts:766, 893).
- Check the server isn't stuck returning redirects/404s by curling the probe URL directly.
- Reproduce by running the server command manually and timing the first 200.
Example fix
# before — probe hits a missing first route, never 200s # pnpm bench:render-pipeline --routes=/nope,/dashboard # after — first route exists, and bump the boot timeout if needed # pnpm bench:render-pipeline --routes=/dashboard,/blog --timeout-ms=60000
Defensive patterns
Strategy: validation
Validate before calling
// confirm the first route returns 200 before the long boot probe depends on it
async function firstRouteOk(base: string, firstRoute: string): Promise<boolean> {
try {
const res = await fetch(`${base}${firstRoute}`, { signal: AbortSignal.timeout(2000) })
return res.ok
} catch { return false }
} Type guard
function isReadinessTimeout(err: unknown): boolean {
return err instanceof Error && /Server did not become ready within/.test(err.message)
} Try / catch
try {
await waitForServerReady(url, timeoutMs, serverDied)
} catch (err) {
if (isReadinessTimeout(err) && !isServerDiedError(err)) {
console.error(`Server alive but never returned 200 within ${timeoutMs}ms. Probe URL: ${url}. Raise --timeout-ms or check the first route.`)
}
throw err
} Prevention
- Make the FIRST route in --routes a fast 200 path — the readiness probe uses routes[0].
- Raise --timeout-ms for legitimately slow boots (large fixture, cold disk).
- curl the probe URL directly to see what the server actually returns.
- Distinguish this (process alive, never 200) from error [14] (process exited) before diagnosing.
When it happens
Trigger: The spawned server stays alive but never answers 2xx within --timeout-ms: extremely slow first compile/build output load, a server stuck in a boot loop that doesn't crash, returning 3xx/4xx forever, or a route that 404s on the probe URL (the probe hits the first route in routeSubset.routes, so a bad first route can keep failing).
Common situations: First route in --routes doesn't exist on the server (probe 404s indefinitely); very slow disk/CPU making boot exceed 30s; the server is up but misconfigured to never return 200 on the probe path.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Server process exited before becoming ready (is port already
- Dev server did not become ready within ${timeoutMs}ms
- Port ${port} is already serving responses — another server i
- Server did not become ready within ${timeoutMs}ms
- Request failed (${response.status}) for ${url}
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/b5a0925e61a8c70e.
Report an issue: GitHub.