remix-run/react-router · critical · Error
No available port found
Error message
No available port found
What it means
Thrown by the `react-router-serve` CLI when neither the preferred port nor an OS-assigned port (port 0) can be bound. `checkPort` resolves `undefined` for `EADDRINUSE` or `EACCES`, so both failing means the host has no bindable TCP port to hand back.
Source
Thrown at packages/react-router-serve/cli.ts:80
);
}
function parseNumber(raw?: string) {
if (raw === undefined) return undefined;
let maybe = Number(raw);
if (Number.isNaN(maybe)) return undefined;
return maybe;
}
async function getAvailablePort(
preferredPort: number,
host?: string,
): Promise<number> {
let preferredAvailablePort = await checkPort(preferredPort, host);
let availablePort = preferredAvailablePort ?? (await checkPort(0, host));
if (availablePort === undefined) {
throw new Error("No available port found");
}
return availablePort;
}
function checkPort(port: number, host?: string): Promise<number | undefined> {
return new Promise((resolve, reject) => {
let server = net.createServer();
let listenOptions = host ? { port, host } : { port };
server.unref();
server.once("error", (error: NodeJS.ErrnoException) => {
if (error.code === "EADDRINUSE" || error.code === "EACCES") {
resolve(undefined);
} else {
reject(error);
}View on GitHub (pinned to 1fd704a7da)
Solutions
- Free or kill whatever holds the ports (e.g. `lsof -i :PORT`, `pkill node`) and retry.
- Pass an explicit free port via the CLI `--port` flag or `PORT` env var.
- If in a container, ensure the exposed port range permits unprivileged binds and that the ephemeral range is not exhausted.
- Run as a user with bind permission for the requested port, or pick a port >1024.
Defensive patterns
Strategy: try-catch
Validate before calling
import net from 'node:net';
async function isPortFree(port: number, host?: string): Promise<boolean> {
return new Promise((resolve) => {
const s = net.createServer();
s.once('error', () => resolve(false));
s.listen({ port, host }, () => s.close(() => resolve(true)));
});
}
// before starting the server:
if (!(await isPortFree(port, host))) {
console.error(`Port ${port} is busy, choose another with --port`);
process.exit(1);
} Try / catch
try {
await run();
} catch (e) {
if (e instanceof Error && e.message === 'No available port found') {
console.error('No bindable port: free a port or pass --port');
process.exit(1);
}
throw e;
} Prevention
- Pass an explicit free `--port` in containers/CI.
- Don't request privileged ports (<1024) as non-root.
- Use orchestration that assigns a host port instead of hardcoding.
When it happens
Trigger: Calling `react-router-serve` (or `getAvailablePort`) on a machine where every attempted port returns EADDRINUSE/EACCES, including the ephemeral-range fallback from `checkPort(0)`. Also triggered by an environment where the unprivileged port range is exhausted or where the process lacks permission to bind any port.
Common situations: Running inside a hardened container/CI sandbox with a restricted port set; SELinux/AppArmor denying the bind; extremely high fd usage leaving no ephemeral ports; a misconfigured `--port` flag pointing at a privileged port (<1024) as a non-root user combined with an ephemeral-range exhaustion.
Related errors
- "${template}" is an invalid template. Run "create-react-rout
- The provided template is not a valid local directory or tarb
- There was a problem extracting the file from the provided te
- There was a problem fetching the file from GitHub. The reque
- There was a problem fetching the file from GitHub. No asset
AI-assisted analysis of remix-run/react-router@1fd704a7da (2026-08-12).
Data as JSON: /api/errors/5d01078cc1f87cba.
Report an issue: GitHub.