{"record":{"id":"5b3284b32f33c59a","repo":"vercel/next.js","slug":"dev-server-did-not-become-ready-within-timeoutms","errorCode":null,"errorMessage":"Dev server did not become ready within ${timeoutMs}ms","messagePattern":"Dev server did not become ready within (.+?)ms","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"bench/dev-validation/benchmark.ts","lineNumber":170,"sourceCode":"    )\n  })\n}\n\nasync function waitForReady(port: number, timeoutMs: number): Promise<void> {\n  const deadline = performance.now() + timeoutMs\n  while (performance.now() < deadline) {\n    try {\n      const res = await fetch(`http://localhost:${port}/`)\n      await res.text()\n      if (res.status < 500) {\n        return\n      }\n    } catch {\n      // Server not up yet.\n    }\n    await sleep(500)\n  }\n  throw new Error(`Dev server did not become ready within ${timeoutMs}ms`)\n}\n\nasync function stopServer(server: ChildProcess): Promise<void> {\n  if (server.exitCode !== null) {\n    return\n  }\n  const exited = new Promise<void>((resolvePromise) =>\n    server.once('exit', () => resolvePromise())\n  )\n  server.kill('SIGTERM')\n  const killed = await Promise.race([\n    exited.then(() => true),\n    sleep(5000).then(() => false),\n  ])\n  if (!killed) {\n    server.kill('SIGKILL')\n    await exited\n  }","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/vercel/next.js/blob/0ae8c72462952df163f1b1e0726641bc5b40dc93/bench/dev-validation/benchmark.ts#L152-L188","documentation":"Thrown by waitForReady (benchmark.ts:170) when, within timeoutMs (called with 180_000 in runOnce), no probe to http://localhost:{port}/ returned a status < 500. The probe loops every 500ms and treats connection failures as 'not up yet'; only a <500 response counts as ready. So this means the dev server never produced even a provisional response in the window — it crashed, hung on first compile, or is unreachable on that host.","triggerScenarios":"runOnce -> waitForReady(port, 180_000) where the spawned `next dev` server: exits with an error (but the spawn uses stdio ['ignore','ignore','inherit'] so only stderr is shown), hangs during first compile (huge module graph / broken config), binds to a different interface than localhost, or the port is wrong. A server stuck returning 5xx during boot also triggers it.","commonSituations":"Port conflict (another process on 3210); a broken next.config / import error in the fixture app that crashes dev startup; an extremely slow first compile on a cold machine; pointing --port at a privileged/occupied port; NEXT_BIN missing so the spawned node fails immediately.","solutions":["Watch the inherited stderr — the dev server's startup error prints there; the cause is usually a config/import error or EADDRINUSE.","Confirm nothing else is on the port (lsof/ss) and that --port matches a free port.","If first-compile is slow, raise the timeout or pre-warm; 180s should cover normal boots, so a timeout usually means a real failure.","Run `node packages/next/dist/bin/next dev` manually in bench/dev-validation to reproduce the startup failure outside the harness."],"exampleFix":"// before\nawait waitForReady(opts.port, 180_000)\n\n// after — surface the server's own stderr so the timeout isn't a blind failure\nconst server = spawn('node', [NEXT_BIN, 'dev', '--port', String(opts.port)], {\n  cwd: APP_DIR,\n  stdio: ['ignore', 'inherit', 'inherit'], // stdout too, not just stderr\n})\nserver.on('exit', (code) => {\n  if (code !== null) throw new Error(`dev server exited with ${code} during boot`)\n})\nawait waitForReady(opts.port, 180_000)","handlingStrategy":"validation","validationCode":"async function portResponds(port: number): Promise<boolean> {\n  try {\n    const res = await fetch(`http://localhost:${port}/`, { signal: AbortSignal.timeout(2000) })\n    return res.status < 500\n  } catch { return false }\n}\n// sanity check before the long harness boot if you suspect the server itself is broken","typeGuard":"function isTimeoutError(err: unknown): boolean {\n  return err instanceof Error && /did not become ready within/.test(err.message)\n}","tryCatchPattern":"// The dev-validation harness calls process.exit(1) on any main() rejection, so wrap\n// only if you want to add diagnostics. Typically you let it fail and inspect stderr:\ntry {\n  await runOnce(worker, opts)\n} catch (err) {\n  if (isTimeoutError(err)) {\n    console.error('Dev server never came up. Run `node packages/next/dist/bin/next dev` in bench/dev-validation to see the error.')\n  }\n  throw err\n}","preventionTips":["Always inherit the spawned server's stderr (and ideally stdout) so boot failures are visible — the harness does for stderr; add stdout for faster diagnosis.","Confirm the port is free before running (ss/lsof).","Keep the fixture app's next.config and imports valid so dev startup doesn't crash.","Run `next dev` manually in the fixture once to confirm it boots before trusting the harness."],"tags":["dev-server","timeout","dev-validation","benchmark","startup"],"analyzedSha":"0ae8c72462952df163f1b1e0726641bc5b40dc93","analyzedAt":"2026-08-06T19:44:29.143Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}