Skip to content

Windows: server.host 'localhost' binds IPv6 only; proxy to localhost:port fails with ECONNREFUSED/ETIMEDOUT #23312

Description

@bayuwicaksono-obs

Describe the bug

On Windows, a Vite dev server configured with server.host: 'localhost' can listen only on IPv6 ([::1]:port).

When another Vite app proxies to http://localhost:port, Node often connects via IPv4 (127.0.0.1), so proxy requests fail.

In the browser this often appears as:

TypeError: Failed to fetch dynamically imported module

even though the target module path is valid.

Reproduction

Environment

  • OS: Windows 10/11 (build 26200)
  • Node: v20.x
  • Vite: 5.4.21
  • Package manager: npm / pnpm

Setup

App A (target), vite.config.ts:

export default defineConfig({
  server: {
    port: 5002,
    host: 'localhost',
  },
});

App B (proxy / hub), vite.config.ts:

export default defineConfig({
  server: {
    port: 5000,
    proxy: {
      '/front-office': {
        target: 'http://localhost:5002',
        changeOrigin: true,
        ws: true,
      },
    },
  },
});

Steps

  1. Start App A (vite, port 5002)
  2. Start App B (vite, port 5000)
  3. Open http://localhost:5000/front-office/
  4. Navigate to a route with lazy / dynamic imports

Observed

  • Hub / proxy logs:
    • http proxy error ... AggregateError [ECONNREFUSED]
    • http proxy error ... AggregateError [ETIMEDOUT]
  • Browser:
    • Failed to fetch dynamically imported module: http://localhost:5000/front-office/@fs/.../index.ts

Network check on Windows

netstat -ano | findstr :5002
# LISTENING on [::1]:5002 (IPv6 only)

curl http://[::1]:5002/front-office/      # 200
curl http://127.0.0.1:5002/front-office/  # fails

Expected behavior

Proxying to http://localhost:5002 should work reliably on Windows when App A is running.

Actual behavior

Proxy requests fail intermittently or consistently because App A is reachable on IPv6 but not IPv4.

Workaround

Set the target app host to 0.0.0.0 (or true):

server: {
  port: 5002,
  host: '0.0.0.0',
}

After this:

  • 127.0.0.1:5002 works
  • hub proxy to localhost:5002 works

Why this matters

server.host: 'localhost' is a common setup. Monorepo setups with a hub app and multiple Vite apps behind a proxy are common, and this failure mode is hard to debug because the browser error points at module import paths, not networking.

Suggested improvements

  1. Document Windows localhost IPv4 / IPv6 behavior for server.host
  2. Warn when dev server is IPv6-only but proxy / client uses localhost
  3. Consider a safer default for Windows proxy / monorepo workflows

Additional context

This is not an application code failure: production build succeeds, and direct access to the target port over IPv6 works before the workaround.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions