vitejs/vite · critical · Error

No available ports found between

Error message

No available ports found between ${startPort} and ${MAX_PORT}

What it means

Thrown when Vite exhausts its port scan from `server.port` (startPort) up to MAX_PORT and every candidate is in use or unavailable on a wildcard address. This only happens with strictPort=false, because strict mode bails on the first port instead of scanning. It means Vite could not find any free port in the configured window to bind the dev/preview server.

Solutions

  1. Reduce concurrent Vite instances, or stagger startup so earlier servers settle before later ones scan.
  2. Pin `server.port` to a known-free high port outside the OS ephemeral range, e.g. `server: { port: 8080 }`.
  3. Set `server.port: 0` to let the OS hand back a free ephemeral port immediately, bypassing the scan.
  4. On Linux, check `sysctl net.ipv4.ip_local_port_range` and raise MAX_PORT or move out of the ephemeral range.
  5. Free wildcard listeners (`ss -ltnp`) that block the availability pre-check on 0.0.0.0/::.
  6. If in CI, allocate isolated network namespaces or randomize `server.port` per job.

Example fix

// before
export default defineConfig({
  server: { port: 5173 }, // all 5173..5173+100 taken
})

// after
export default defineConfig({
  server: { port: 0 }, // OS picks a free port
})
Defensive patterns

Strategy: validation

Validate before calling

import net from 'node:net'

async function firstFreePort(start: number, max: number): Promise<number | null> {
  for (let p = start; p <= max; p++) {
    const free = await new Promise<boolean>((res) => {
      const t = net.createServer().once('error', () => res(false)).once('listening', () => t.close(() => res(true)))
      t.listen(p)
    })
    if (free) return p
  }
  return null
}
// Pre-check the window before starting Vite
const p = await firstFreePort(5173, 5273)
if (!p) throw new Error('Port range exhausted before Vite start')

Try / catch

try {
  await server.listen()
} catch (e) {
  if (e instanceof Error && /No available ports found/.test(e.message)) {
    // fall back to OS-assigned ephemeral port
    await server.listen(0)
  } else throw e
}

Prevention

When it happens

Trigger: Loop at http.ts:277 iterates `port` from startPort to MAX_PORT; each port either fails `isPortAvailable` (wildcard 0.0.0.0/:: check) or fails `tryBindServer` with EADDRINUSE. After the loop ends at line 314, the error is thrown. Triggered when a host machine has a long contiguous block of occupied ports (e.g. many dev servers, browser port range exhaustion).

Common situations: Running dozens of Vite instances in parallel test grids. Linux ephemeral port range (`net.ipv4.ip_local_port_range`) overlapping 5173–5273. A proxy or VPN client grabbing a port range. Port scanners / security tools holding ranges. Misconfigured `MAX_PORT` window.

Related errors


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

Appendix: source

Thrown at packages/vite/src/node/http.ts:314

      }
      if (result.error.code !== 'EADDRINUSE') {
        throw result.error
      }
      throw new Error(`Port ${port} is already in use`)
    }

    if (portAvailableOnWildcard) {
      const result = await tryBindServer(httpServer, port, host)
      if (result.success) {
        return port
      }
      if (result.error.code !== 'EADDRINUSE') {
        throw result.error
      }
    }
    logger.info(`Port ${port} is in use, trying another one...`)
  }
  throw new Error(
    `No available ports found between ${startPort} and ${MAX_PORT}`,
  )
}

export function setClientErrorHandler(
  server: HttpServer,
  logger: Logger,
): void {
  server.on('clientError', (err, socket) => {
    // https://github.com/nodejs/node/blob/v26.2.0/lib/_http_server.js#L992
    let msg
    switch ((err as any).code) {
      case 'HPE_HEADER_OVERFLOW': {
        msg = '431 Request Header Fields Too Large'
        logger.warn(
          colors.yellow(
            'Server responded with status code 431. ' +
              'See https://vite.dev/guide/troubleshooting.html#_431-request-header-fields-too-large.',

View on GitHub (pinned to b4d66fee14)