vercel/next.js · error
Port ${port} is already serving responses — another server i
Error message
Port ${port} is already serving responses — another server is running. Stop it, pass a different --port, or use --start-server=false to trace against it deliberately. What it means
Thrown by assertPortFree before starting a server when an HTTP GET to http://127.0.0.1:{port}/ already returns a response. This prevents the contested-port race where a stale server answers the readiness probe while the new child fails to bind, causing the tracer to silently measure the wrong (old) server. The error message offers three explicit escapes.
Source
Thrown at bench/render-pipeline/client-trace.ts:266
}
// 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 {
return
} finally {
clearTimeout(timeout)
}
throw new Error(
`Port ${port} is already serving responses — another server is running. ` +
`Stop it, pass a different --port, or use --start-server=false to ` +
`trace against it deliberately.`
)
}
async function gracefulKill(server: ReturnType<typeof spawn>) {
// once('exit') never resolves for a child that already exited.
if (server.exitCode !== null || server.signalCode !== null) return
const tryKill = async (signal: NodeJS.Signals, timeoutMs: number) => {
server.kill(signal)
const didExit = await Promise.race([
once(server, 'exit')
.then(() => true)
.catch(() => true),
sleep(timeoutMs).then(() => false),
])
return didExitView on GitHub (pinned to 0ae8c72462)
Solutions
- Stop the existing server: lsof -ti:PORT | xargs kill, or close the dev terminal.
- Pass a different --port that is free.
- Pass --start-server=false to deliberately trace against the already-running server (you accept it is the target).
Example fix
# before: port busy, ambiguous target pnpm bench:render-pipeline:client --port=3199 # after: free the port first lsof -ti:3199 | xargs kill -9 pnpm bench:render-pipeline:client --port=3199
Defensive patterns
Strategy: validation
Validate before calling
// Reuse the tracer's own logic: if something answers, decide deliberately
async function portHasServer(port: number): Promise<boolean> {
try {
await fetch(`http://127.0.0.1:${port}/`, { signal: AbortSignal.timeout(1000) })
return true
} catch { return false }
}
if (await portHasServer(port) && !options.attachToExisting) {
throw new Error(`Stop the server on ${port} or pass a different --port`)
} Type guard
null
Try / catch
null
Prevention
- Kill prior servers between benchmark runs.
- Use --start-server=false only when deliberately attaching to a known server.
- Vary --port across concurrent benchmark jobs.
When it happens
Trigger: A previous next dev/start (or any HTTP server) is still bound to the port; a different benchmark left a process running; an unrelated dev server (Vite, Express) occupies the port.
Common situations: Iterating on benchmarks without killing the prior server; a crashed benchmark left an orphan server; running multiple trace jobs concurrently on the default port.
Related errors
- Server process exited before becoming ready (is port already
- Port ${port} is already serving responses — another server i
- Server process exited before becoming ready (is port already
- Invalid --top value: ${topRaw}
- Invalid numeric value for --${key}: ${value}
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/03c66b12883c9404.
Report an issue: GitHub.