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

  1. Do not call server.listen() in middleware mode — the parent HTTP server already listens; you only need app.use(vite.middlewares).
  2. If you want Vite to manage listening, remove server.middlewareMode from the config.
  3. 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

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


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)