Skip to content

WebSocket connections proxying not working (uses http, not ws) #20223

Open
@LeoVasanko

Description

@LeoVasanko

Describe the bug

I have my vite config setup as follows:

 server: {
    proxy: {
      "/api": {
        target: "ws://localhost:8078",
        changeOrigin: false,
        ws: true
      }

Despite the ws setting and ws:// target, WebSocket requests to /api get processed as HTTP. This is apparent from Connection: keep-alive header sent to backend (should be Connection: Upgrade), and from the fact that actual WebSocket communications don't appear to be passing through even if I force-set the header on backend side so that it still gets processed as a WebSocket connection there. Upgrade: websocket header is present from the request the browser makes to Vite, to the backend.

For the sake of simplicity, testing only what headers get sent to the backend port (8078):

$ nc -l 8078    # new WebSocket("ws://localhost:8077/api") // Vite
GET /api HTTP/1.1
accept: */*
accept-encoding: gzip, deflate, br, zstd
accept-language: en-US,en;q=0.9
host: localhost:8077
referer: http://localhost:8077/register
sec-ch-ua: "Brave";v="137", "Chromium";v="137", "Not/A)Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-origin
sec-gpc: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36
Connection: keep-alive

^C⏎
$ nc -l 8078    # new WebSocket("ws://localhost:8078/api") // Directly to nc (backend)
GET /api HTTP/1.1
Host: localhost:8078
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36
Accept-Language: en-US,en;q=0.9
Upgrade: websocket
Origin: http://localhost:8077
Sec-WebSocket-Version: 13
Accept-Encoding: gzip, deflate, br, zstd
Sec-WebSocket-Key: ulPCryvhCoCiS9yI3Timiw==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

^C⏎

I am also pretty sure that the same configuration worked with the same project before, using some earlier version of Vite and possibly NPM or Yarn rather than Bun.

Reproduction

https://git.zi.fi/leo/wsproxytest

Steps to reproduce

The repository contains minimal Vite project and server. See the README for further instructions.

System Info

System:
    OS: Linux 6.6 Ubuntu 24.04.2 LTS 24.04.2 LTS (Noble Numbat)
    CPU: (28) x64 Intel(R) Core(TM) i7-14700
    Memory: 115.91 GB / 125.57 GB
    Container: Yes
    Shell: 3.7.0 - /usr/bin/fish
  Binaries:
    npm: 10.9.2 - /mnt/c/Program Files/nodejs/npm
    bun: 1.2.6 - /tmp/bun-node-8ebd5d53d/bun
  npmPackages:
    vite: ^6.3.5 => 6.3.5

Used Package Manager

bun

Logs

No response

Validations

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions