vitejs/vite · error · Error

Cannot print server URLs in middleware mode.

Error message

Cannot print server URLs in middleware mode.

What it means

ViteDevServer.printUrls at packages/vite/src/node/server/index.ts:798 throws in middleware mode (server.middlewareMode = true). In middleware mode Vite does not own the listening socket, so it cannot know the bound port/host and resolvedUrls stays null; printing URLs would be misleading.

Source

Thrown at packages/vite/src/node/server/index.ts:798

      } else {
        server.config.logger.warn('No URL available to open in browser')
      }
    },
    async close() {
      if (!closeServerPromise) {
        closeServerPromise = closeServer()
      }
      return closeServerPromise
    },
    printUrls() {
      if (server.resolvedUrls) {
        printServerUrls(
          server.resolvedUrls,
          serverConfig.host,
          config.logger.info,
        )
      } else if (middlewareMode) {
        throw new Error('Cannot print server URLs in middleware mode.')
      } else {
        throw new Error(
          'Cannot print server URLs before server.listen is called.',
        )
      }
    },
    bindCLIShortcuts(options) {
      bindCLIShortcuts(server, options)
    },
    async restart(forceOptimize?: boolean) {
      if (!server._restartPromise) {
        server._forceOptimizeOnRestart = !!forceOptimize
        server._restartPromise = restartServer(server).finally(() => {
          server._restartPromise = null
          server._forceOptimizeOnRestart = false
        })
      }
      return server._restartPromise

View on GitHub (pinned to 89620f09af)

Solutions

  1. Do not call printUrls() in middleware mode — the parent server is responsible for printing its own URLs.
  2. If you want to advertise Vite, print the URL from the outer httpServer.listen callback using the host/port you control.
  3. Drop server.middlewareMode if you want Vite to manage the socket and print URLs itself.

Example fix

// before
const server = await createServer({ server: { middlewareMode: true } })
server.printUrls() // throws

// after
const server = await createServer({ server: { middlewareMode: true } })
app.use(server.middlewares)
http.createServer(app).listen(3000, () =>
  console.log('http://localhost:3000'),
)
Defensive patterns

Strategy: validation

Validate before calling

function assertNotMiddlewareMode(server: { middlewareMode?: boolean }) {
  if (server.middlewareMode) {
    throw new Error('printUrls is unavailable in middleware mode; the parent server owns the socket')
  }
}

Type guard

function isMiddlewareMode(server: { middlewareMode?: boolean }): boolean {
  return !!server.middlewareMode
}

Prevention

When it happens

Trigger: Calling server.printUrls() when the dev server was created with server.middlewareMode: true (common when mounting Vite inside an existing express/connect/Next.js server).

Common situations: SSR setups embedding Vite as middleware; custom servers (Polyserver, Nest, Fastify) wrapping Vite; copy-paste of the standalone printUrls call into a middleware-mode setup.

Related errors


AI-assisted analysis of vitejs/vite@89620f09af (2026-08-03). Data as JSON: /data/errors/9efcb70f1d612355.json. Report an issue: GitHub.