global-setup polls baseURL/health via Node fetch; the runner resolves localhost to ::1 first, but Vite binds IPv4-only (127.0.0.1:5173), so localhost→::1:5173 → ECONNREFUSED → health poll never returns 200. (curl passed for :3000 because curl falls back IPv4↔IPv6 and the API is dual-stack; Node fetch does not.) Proven: [::1]:5173 ECONNREFUSED vs 127.0.0.1:5173 200. Point PLAYWRIGHT_BASE_URL at 127.0.0.1 and add --dns-result-order=ipv4first. No harness files changed.