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

  1. Free up ports: stop orphan processes or raise the OS ephemeral range (sysctl net.ipv4.ip_local_port_range).
  2. Wait for TIME_WAIT sockets to recycle (default ~60s) before restarting.
  3. 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

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


AI-assisted analysis of vitejs/vite@b4d66fee14 (2026-08-11). Data as JSON: /api/errors/0c75e1e13955fe5c. Report an issue: GitHub.