vitejs/vite · error · Error
No available ephemeral port found
Error message
No available ephemeral port found
What it means
When server.port is 0 (ephemeral), Vite calls getAvailableEphemeralPort to find a free port. If it returns null (no free port in the ephemeral range after retries), Vite throws 'No available ephemeral port found'. A subsequent bind race can also surface the related 'Port X is already in use' message.
Source
Thrown at packages/vite/src/node/http.ts:263
}
const MAX_PORT = 65535
export async function httpServerStart(
httpServer: HttpServer,
serverOptions: {
port: number
strictPort: boolean | undefined
host: string | undefined
logger: Logger
},
): Promise<number> {
const { port: startPort, strictPort, host, logger } = serverOptions
if (startPort === 0) {
const port = await getAvailableEphemeralPort(host)
if (port == null) {
throw new Error('No available ephemeral port found')
}
const result = await tryBindServer(httpServer, port, host)
if (result.success) {
return port
}
if (result.error.code !== 'EADDRINUSE') {
throw result.error
}
// this can happen if the port was listened by other process between getAvailableEphemeralPort and tryBindServer
throw new Error(`Port ${port} is already in use`)
}
for (let port = startPort; port <= MAX_PORT; port++) {
// Pre-check port availability on wildcard addresses (0.0.0.0, ::)
// so that we avoid conflicts with other servers listening on all interfaces
const portAvailableOnWildcard = await isPortAvailable(port)
View on GitHub (pinned to b4d66fee14)
Solutions
- Free up ports: stop orphan processes or raise the OS ephemeral range (sysctl net.ipv4.ip_local_port_range).
- Wait for TIME_WAIT sockets to recycle (default ~60s) before restarting.
- Pin an explicit server.port with strictPort: false so Vite can scan upward.
Example fix
// before
server: { port: 0, strictPort: true }
// after
server: { port: 5173, strictPort: false } Defensive patterns
Strategy: retry
Validate before calling
function detectPortExhaustion(host) {
return new Promise((resolve) => {
require('net').createServer().once('error', () => resolve(true)).listen(0, host, () => resolve(false));
});
} Try / catch
let attempts = 0;
async function startServer(server) {
while (attempts < 3) {
try { return await server.listen(); }
catch (e) {
if (/No available ephemeral port/.test(String(e.message)) && attempts < 2) { attempts++; await new Promise((r) => setTimeout(r, 1000)); continue; }
throw e;
}
}
} Prevention
- Raise the OS ephemeral port range on CI runners.
- Reuse a single dev server across watch tasks instead of spawning many.
- Pin server.port to a known-free value when possible.
When it happens
Trigger: Starting the dev server with server.port: 0 on a machine where the ephemeral range (typically 1024-65535) is exhausted - all candidate ports are bound, in TIME_WAIT, or otherwise unavailable.
Common situations: Heavy containerized CI with many concurrent Vite instances; systems with very low ephemeral port ranges (net.ipv4.ip_local_port_range); exhausted ports due to crashed processes holding sockets.
Related errors
- Port ${port} is already in use
- HTTP server not available
- No available ports found between ${startPort} and ${MAX_PORT
- client ID conflict detected. Please restart the dev server.
- Environment "${name}" is not defined in the config.
AI-assisted analysis of vitejs/vite@b4d66fee14 (2026-08-11).
Data as JSON: /api/errors/0c75e1e13955fe5c.
Report an issue: GitHub.