nestjs/nest · error · Error
Server did not become ready in ${timeoutMs}ms: ${url}
Error message
Server did not become ready in ${timeoutMs}ms: ${url} What it means
An internal readiness guard in the benchmarks CLI (tools/benchmarks/src/main.ts:137). runOne forks a framework server (express/fastify/nest-express/nest-fastify) as a child process, then waitForServer polls the target URL with global fetch every 100ms; if it never returns 200 or 404 within timeoutMs (default 5000), it throws a plain Error with this message, aborting the whole benchmark run. Because the child is forked with stdio:'ignore', the underlying startup error is hidden — the timeout is the only symptom.
Source
Thrown at tools/benchmarks/src/main.ts:137
const hasFetch = typeof (globalThis as any).fetch === 'function';
while (Date.now() - start < timeoutMs) {
try {
if (hasFetch) {
const res = await (globalThis as any).fetch(url, { method: 'GET' });
if (res && (res.status === 200 || res.status === 404)) return;
} else {
// best-effort fallback
await sleep(250);
return;
}
} catch {
// server not ready yet
}
await sleep(100);
}
throw new Error(`Server did not become ready in ${timeoutMs}ms: ${url}`);
}
function killChild(child: ChildProcess): void {
if (!child || child.killed) return;
// Try graceful termination first.
try {
child.kill('SIGTERM');
} catch {
// ignore
}
// Force kill if still alive shortly after.
setTimeout(() => {
try {
if (!child.killed) child.kill('SIGKILL');
} catch {
// ignoreView on GitHub (pinned to 6ec0e2783d)
Solutions
- Free port 3000 (lsof/iOSTAT or pick --port) before running the benchmark.
- Build the framework bundles first so fork() resolves a real entry file.
- Temporarily change stdio from 'ignore' to 'inherit' to see the child's startup error.
- Raise the timeout (waitForServer(url, 15_000)) on slow machines, and surface child stderr in the thrown message.
Example fix
// before
const child = fork(frameworkEntry(framework), { stdio: 'ignore' });
...
throw new Error(`Server did not become ready in ${timeoutMs}ms: ${url}`);
// after
const child = fork(frameworkEntry(framework), { stdio: 'inherit' });
child.stderr?.on('data', d => console.error(`[${framework}]`, d.toString()));
await waitForServer(url, 15_000); Defensive patterns
Strategy: retry
Validate before calling
// Before running, ensure the port is free and the bundle is built.
import { createServer } from 'node:net';
async function isPortFree(port: number): Promise<boolean> {
return new Promise(resolve => {
const tester = createServer();
tester.once('error', () => resolve(false));
tester.once('listening', () => tester.close(() => resolve(true)));
tester.listen(port);
});
}
if (!(await isPortFree(args.port))) {
throw new Error(`port ${args.port} is already in use`);
} Type guard
function isChildError(e: unknown, codes: string[]): boolean {
return typeof e === 'object' && e !== null
&& codes.includes((e as NodeJS.ErrnoException).code ?? '');
} Try / catch
try {
await runOne(framework, args);
} catch (e) {
if (e instanceof Error && /did not become ready/.test(e.message)) {
// inspect child stderr (switch stdio to 'inherit'), free the port, or raise timeout
console.error('startup failed — re-run with stdio: inherit');
}
throw e;
} Prevention
- Check the port is free before forking.
- Build framework bundles before running so fork() resolves a real entry file.
- Run child with stdio 'inherit' during local debugging to see startup errors.
- Make the readiness timeout configurable and surface child stderr in the thrown message.
When it happens
Trigger: Running `npm run benchmarks` when the forked framework process crashes on boot, binds the wrong port, or never listens — e.g., port 3000 already in use, missing compiled bundle at the forked entry path, framework built for an incompatible Node version, or a slow CI box exceeding the 5s budget.
Common situations: Another dev server already occupying :3000; dist/ not built (node resolves a path with no compiled JS); framework entry file path changed after a refactor; child crashes synchronously on import but stdio:'ignore' swallows it; CI runner under load.
AI-assisted analysis of nestjs/nest@6ec0e2783d (2026-08-03).
Data as JSON: /data/errors/027cd31ca72c4181.json.
Report an issue: GitHub.