vitejs/vite · error · Error
Port ${port} is already in use
Error message
Port ${port} is already in use What it means
Thrown by `httpServer` port resolution when `strictPort: true` and the requested port cannot be bound (the bind attempt returns `EADDRINUSE`). With strictPort Vite refuses to silently move to another port, so it surfaces the conflict directly. The throw is at http.ts:252, after re-binding confirms the failure is an in-use error.
Source
Thrown at packages/vite/src/node/http.ts:252
// If port is not available on a wildcard address but strictPort is set,
// we still try binding directly before giving up.
if (strictPort) {
const result = await tryBindServer(httpServer, port, host)
if (result.success) {
if (!portAvailableOnWildcard) {
logger.warn(
colors.yellow(
`Port ${port} is in use on a wildcard address, but ${host ?? 'localhost'}:${port} is available. ` +
`There may be another server running on a wildcard IP on port ${port}.`,
),
)
}
return port
}
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}`,
)
}
View on GitHub (pinned to 89620f09af)
Solutions
- Free the port: find the process with `lsof -i :<port>` / `netstat -ano` and stop it, or restart your machine/WSL.
- Set `strictPort: false` (default) so Vite auto-increments to the next free port.
- Change `server.port` to a free port in the config.
- If the holder is your own orphaned process, run `tman kill`/`kill -9 <pid>`.
Example fix
// before
export default defineConfig({ server: { port: 5173, strictPort: true } })
// after
export default defineConfig({ server: { port: 5173, strictPort: false } }) Defensive patterns
Strategy: validation
Validate before calling
import net from 'node:net'
async function isFree(port: number, host?: string): Promise<boolean> {
return new Promise((res) => {
const s = net.createServer()
s.unref().once('error', () => res(false)).listen(port, host, () => s.close(() => res(true)))
})
}
// before createServer: if (config.server.strictPort && !(await isFree(port))) throw ... Try / catch
try {
await createServer(config)
} catch (e) {
if (e instanceof Error && /already in use/.test(e.message)) {
// free the port or switch config.server.port / strictPort and retry once
} else throw e
} Prevention
- Pre-check port availability before strictPort binds.
- Default strictPort to false in shared/team configs to avoid hard failures.
- Use a deterministic per-project port to reduce collisions.
When it happens
Trigger: Starting `createServer`/`createPreviewServer` with `server.strictPort: true` (or `preview.strictPort: true`) while the configured `server.port` is already bound by another process.
Common situations: A previous dev server didn't shut down cleanly; another app (or a second Vite instance) holds the port; Docker/WSL port forwarding conflicts; running multiple projects on port 5173/3000.
Related errors
- No available ports found between ${startPort} and ${MAX_PORT
- { runtime: "${result.runtime}" } is not supported for assets
- `renderLegacyChunks` and `renderModernChunks` cannot be both
- @vitejs/plugin-legacy does not support library mode.
- HMR is not supported by this runner transport, but `hmr` opt
AI-assisted analysis of vitejs/vite@89620f09af (2026-08-03).
Data as JSON: /data/errors/1b93d9782900a563.json.
Report an issue: GitHub.