Skip to content

server.host specific IP still fails because Vite pre-checks 0.0.0.0/:: before binding #22125

@matheustav

Description

@matheustav

Describe the bug

When server.host is set to a specific IP address, Vite still rejects the configured port if that port is already in use on a different local interface.

In my case, I set server.host = '127.0.20.4', server.port = 80, and server.strictPort = true. The address 127.0.20.4:80 is actually free, and I can bind to it successfully with a plain Bun server. However, Vite exits with:

Error: Port 80 is already in use

Minimal config

vite.config.js

import { defineConfig } from 'vite'

export default defineConfig({
  server: {
    host: '127.0.20.4',
    port: 80,
    strictPort: true,
  },
})

Reproduction context

I also have other local services listening on port 80, but on different loopback aliases, for example 127.0.10.10:80, 127.0.10.15:80, 127.0.10.30:80, and 127.0.10.40:80.

Nothing is listening on 127.0.20.4:80.

Investigation

I patched net.Server.prototype.listen to log listen attempts. Before trying the configured host, Vite first tries:

LISTEN_CALL:net [ 80, "0.0.0.0" ]

and that fails with EADDRINUSE.

The stack trace points to Vite's internal port availability check before the actual bind to the configured host.

From the current source, httpServerStart() calls isPortAvailable(port) before the real bind, and isPortAvailable(port) checks wildcard hosts (0.0.0.0, ::) rather than the configured server.host.

Expected behavior

If server.host is a specific IP, I would expect Vite to consider the port available when that exact host + port is free, even if the same port is in use on other local IPs.

Why this seems incorrect

The docs say server.host specifies which IP addresses the server should listen on. In this case, Vite appears to reject the port based on wildcard availability instead of the requested host+port combination.

Reproduction (can't post a link for this, sorry. Needs to be tested with different hosts)

// Pre-check port availability on wildcard addresses (0.0.0.0, ::)

Steps to reproduce

  1. Add these entries to /etc/hosts if needed:
    127.0.20.4 vite-test.local
    127.0.10.10 busy-a.local
    127.0.10.15 busy-b.local
    127.0.10.30 busy-c.local
    127.0.10.40 busy-d.local

  2. Start any HTTP servers on port 80 for the following loopback aliases:
    127.0.10.10:80
    127.0.10.15:80
    127.0.10.30:80
    127.0.10.40:80

  3. Verify that nothing is listening on 127.0.20.4:80.

  4. Run:
    npm install
    npm run dev

  5. Observe that Vite fails with:
    Error: Port 80 is already in use

  6. For comparison, binding directly to 127.0.20.4:80 with a plain Bun server works.

System Info

Vite 8.0.3
Bun 1.3.6 (also tested on Node.js v25.2.1, same error)
Linux

Used Package Manager

bun

Logs

demo-vue dev $ bunx --bun vite
│ error when starting dev server:
│ Error: Port 80 is already in use
│ at httpServerStart (/home/blabla/node_modules/vite/dist/node/chunks/node.js:10635:29)
│ at async startServer (/home/blabla/node_modules/vite/dist/node/chunks/node.js:26219:36)
│ at async listen (/home/blabla/node_modules/vite/dist/node/chunks/node.js:26040:10)
│ at async (/home/blabla/node_modules/vite/dist/node/cli.js:722:16)
│ at processTicksAndRejections (native:7:39)
└─ Exited with code 1
error: script "dev:vue" exited with code 1

Validations

Metadata

Metadata

Labels

feat: devdev serverp2-edge-caseBug, but has workaround or limited in scope (priority)

Type

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions