vercel/next.js · error
Server process exited before becoming ready (is port already
Error message
Server process exited before becoming ready (is port already in use?)
What it means
Thrown by waitForServerReady when the spawned dev/start server process exits (serverDied() returns true) before the readiness probe ever succeeds. This distinguishes a dead server from a slow one and specifically guards against the contested-port race where a stale server answers the probe while the new child fails to bind (EADDRINUSE). Without it, the tracer would silently measure the wrong server.
Source
Thrown at bench/render-pipeline/client-trace.ts:234
throw new Error(
`Command failed: ${command} ${args.join(' ')} (exit ${code})`
)
}
}
async function waitForServerReady(
url: string,
timeoutMs: number,
serverDied?: () => boolean
): Promise<void> {
const start = performance.now()
while (performance.now() - start < timeoutMs) {
// 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`)
}
// 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.View on GitHub (pinned to 0ae8c72462)
Solutions
- Free the port: find and kill the process (lsof -i :PORT then kill), or pass --port with a free value.
- Rebuild the fixture (pnpm --filter=next build) if next start is crashing on missing output.
- Run next start manually in the fixture dir to see the crash reason.
- Ensure no required environment variables are missing.
Example fix
# before: stale server holds the port next start # exits with EADDRINUSE # after lsof -ti:3199 | xargs kill; next start --port 3199
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the port is free before spawning the server
import net from 'node:net'
async function isPortFree(port: number): Promise<boolean> {
return new Promise(resolve => {
const tester = net.createServer()
tester.once('error', () => resolve(false))
tester.listen(port, () => tester.close(() => resolve(true)))
})
}
if (!(await isPortFree(port))) {
throw new Error(`Free port ${port} before starting (lsof -ti:${port} | xargs kill)`)
} Type guard
null
Try / catch
null
Prevention
- Always free the port or pick a fresh one before each run.
- Run next start manually in the fixture to catch startup crashes.
- Rebuild after branch switches so next start has valid output.
When it happens
Trigger: The server child crashes on startup; EADDRINUSE because another process owns the port; the build output is missing or corrupt so next start exits immediately; a required env var is unset causing an early fatal.
Common situations: A previous benchmark left a server running on the same port; switching branches without rebuilding so next start fails; missing NEXT_BIN or built artifacts.
Related errors
- Server process exited before becoming ready (is port already
- 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
- Port ${port} is already serving responses — another server i
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/3c996673fb3e250c.
Report an issue: GitHub.