vitejs/vite · error · Error
Cannot print server URLs before server is listening.
Error message
Cannot print server URLs before server is listening.
What it means
PreviewServer.printUrls at packages/vite/src/node/preview.ts:191 throws if server.resolvedUrls is null. resolvedUrls is only populated after the HTTP server is listening, so calling printUrls before awaiting the listen step has no URLs to print.
Source
Thrown at packages/vite/src/node/preview.ts:191
server.resolvedUrls = null
}
const server: PreviewServer = {
config,
middlewares: app,
httpServer,
async close() {
if (!closeServerPromise) {
closeServerPromise = closeServer()
}
return closeServerPromise
},
resolvedUrls: null,
printUrls() {
if (server.resolvedUrls) {
printServerUrls(server.resolvedUrls, options.host, logger.info)
} else {
throw new Error('Cannot print server URLs before server is listening.')
}
},
bindCLIShortcuts(options) {
bindCLIShortcuts(server as PreviewServer, options)
},
}
const closeServerAndExit = async (_: unknown, exitCode?: number) => {
try {
await server.close()
} finally {
process.exitCode ??= exitCode ? 128 + exitCode : undefined
process.exit()
}
}
setupSIGTERMListener(closeServerAndExit)
View on GitHub (pinned to 89620f09af)
Solutions
- Await server.listen(previewPort) (or httpServer.listen) before calling server.printUrls().
- Move printUrls() into the listen callback / .then so resolvedUrls is populated.
- If you do not need to print URLs, simply omit the call.
Example fix
// before
const server = await preview({})
server.printUrls()
// after
const server = await preview({})
await server.httpServer.listen(4173)
server.printUrls() Defensive patterns
Strategy: validation
Validate before calling
function assertListening(server: { resolvedUrls: unknown }) {
if (!server.resolvedUrls) {
throw new Error('call httpServer.listen() before printUrls()')
}
}
assertListening(server) Type guard
function isListening(server: { resolvedUrls: unknown }): boolean {
return server.resolvedUrls != null
} Prevention
- Call printUrls only after the listen promise/callback fires.
- Treat resolvedUrls as the source of truth for whether the server is bound.
- In tests, skip printUrls and assert on httpServer.address() instead.
When it happens
Trigger: Calling server.printUrls() synchronously after createPreviewServer without first awaiting httpServer.listen(port); calling printUrls inside an error path where listening failed; test harness that constructs the server and immediately prints URLs.
Common situations: Custom scripts wrapping preview that forget the listen step; copy-paste from dev-server examples that auto-print on listen but applied to a preview server used manually.
Related errors
- Cannot print server URLs before server.listen is called.
- Vite module runner has been closed.
- [module runner] HMR client was closed.
- Port ${port} is already in use
- No available ports found between ${startPort} and ${MAX_PORT
AI-assisted analysis of vitejs/vite@89620f09af (2026-08-03).
Data as JSON: /data/errors/10c1a3323fb5f481.json.
Report an issue: GitHub.