vitejs/vite · error · Error
Cannot call server.listen in middleware mode.
Error message
Cannot call server.listen in middleware mode.
What it means
Thrown by startServer() (invoked from server.listen()) when server.httpServer is absent, which is exactly the case in middleware mode. In middleware mode Vite does not create a Node http.Server, so binding a port is meaningless and is rejected.
Solutions
- Do not call server.listen() in middleware mode — the parent HTTP server already listens; you only need app.use(vite.middlewares).
- If you want Vite to manage listening, remove server.middlewareMode from the config.
- Guard the call: if (!vite.config.server.middlewareMode) await vite.listen().
Example fix
// before
const vite = await createServer({ server: { middlewareMode: true } })
await vite.listen(5173) // throws
// after
const vite = await createServer({ server: { middlewareMode: true } })
app.use(vite.middlewares)
app.listen(5173) Defensive patterns
Strategy: validation
Validate before calling
if (!server.config.server.middlewareMode) {
await server.listen(port)
} Prevention
- Reserve server.listen() for standalone mode only.
- In middleware mode, only call app.use(vite.middlewares); let the parent server listen.
When it happens
Trigger: Calling server.listen(port) on a server created with server.middlewareMode: true. The check `if (!httpServer)` at server/index.ts:1105 detects that there is no listener to bind.
Common situations: Using Vite as middleware inside an existing HTTP server and accidentally also calling server.listen. Copying standalone-server sample code into a middleware-mode integration. Race between custom server bootstrap and Vite listen call.
Related errors
- Cannot print server URLs before server.listen is called.
- Cannot print server URLs in middleware mode.
- HTTP server not available
- There is already a server associated with the config.
- Cannot print server URLs before server is listening.
AI-assisted analysis of vitejs/vite@b4d66fee14 (2026-08-11).
Data as JSON: /api/errors/8841d86b5e6b51e6.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vite/src/node/server/index.ts:1106
return
}
return listen(port, ...args)
}) as any
} else {
await initServer(false)
}
return server
}
async function startServer(
server: ViteDevServer,
hostname: Hostname,
inlinePort?: number,
): Promise<void> {
const httpServer = server.httpServer
if (!httpServer) {
throw new Error('Cannot call server.listen in middleware mode.')
}
const options = server.config.server
const configPort = inlinePort ?? options.port
// When using non strict port for the dev server, the running port can be different from the config one.
// When restarting, the original port may be available but to avoid a switch of URL for the running
// browser tabs, we enforce the previously used port, except if the config port changed.
const port =
configPort === server._configServerPort
? (server._currentServerPort ?? configPort)
: configPort
server._configServerPort = configPort
const serverPort = await httpServerStart(httpServer, {
port,
strictPort: options.strictPort,
host: hostname.host,
logger: server.config.logger,View on GitHub (pinned to b4d66fee14)