Vite strictPort doesn't detect a port clash when another server holds the same port on IPv4 (macOS)
On macOS (Darwin 25), two Vite dev servers from different projects were both started with vite dev --port 5187, one with server.strictPort: true. Neither printed Port 5187 is already in use; both reported ready. Requests then went to the wrong app depending on the client: curl http://127.0.0.1:5187/ returned project B's HTML, while curl 'http://[::1]:5187/' returned project A's. A reverse proxy aimed at http://127.0.0.1:5187 would quietly serve the other project. lsof -nP -iTCP:5187 -sTCP:LISTEN showed two node processes: [::1]:5187 and *:5187. A readiness probe on 127.0.0.1:<port> for project A also never succeeded even though Vite printed Local: http://localhost:<port>/.
Root cause: Vite's default server.host is localhost. On macOS, Node resolves localhost to ::1 first, so Vite binds [::1]:<port> only, not 127.0.0.1. A second process listening on the IPv4 wildcard (*:<port>, e.g. a Vite config with host: true / 0.0.0.0) is a separate socket, so neither bind fails with EADDRINUSE, and strictPort has nothing to detect. Clients then split by address family: anything dialing 127.0.0.1 gets the IPv4 listener, anything dialing [::1] gets the IPv6 one, and localhost depends on the client's resolution order.
Diagnose:
lsof -nP -iTCP:<port> -sTCP:LISTEN # look for both [::1]:<port> and *:<port> / 127.0.0.1:<port>
for p in $(lsof -tiTCP:<port> -sTCP:LISTEN); do ps -o pid=,command= -p $p; lsof -a -p $p -d cwd -Fn | grep ^n; doneFix: give each project a unique port (the real fix). To make clashes fail loudly, pin the host so both projects bind the same address family, e.g. server: { host: '127.0.0.1', port, strictPort: true }; then the second server gets EADDRINUSE and exits. Readiness probes and proxies should target the address Vite actually bound ([::1] with the default host), or set the host explicitly.