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
- Reduce concurrent Vite instances, or stagger startup so earlier servers settle before later ones scan.
- Pin `server.port` to a known-free high port outside the OS ephemeral range, e.g. `server: { port: 8080 }`.
- Set `server.port: 0` to let the OS hand back a free ephemeral port immediately, bypassing the scan.
- On Linux, check `sysctl net.ipv4.ip_local_port_range` and raise MAX_PORT or move out of the ephemeral range.
- Free wildcard listeners (`ss -ltnp`) that block the availability pre-check on 0.0.0.0/::.
- 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
- Limit the number of concurrent Vite servers per host.
- Move server.port out of the OS ephemeral range (check net.ipv4.ip_local_port_range on Linux).
- Use server.port: 0 in environments where any free port is acceptable.
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
- Cannot print server URLs before server is listening.
- failed to resolve rolldownOptions.input value
- No available ephemeral port found
- Port is already in use
- The following dependencies are imported but could not be…
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)