create-react-app: WebSocket connection to 'ws://localhost:3000/ws' failed:

Basic React App doesn’t work because the websocket connection appears to be hardcoded to port 3000. Part of this appears to be related to running in a container, but I’ve discovered additional issues even when running local.

Example project here - https://github.com/Fosol/bug-hot-reload

npm: 7.24.0 yarn: 1.22.5 node: v16.10.0 react-scripts: 5.0.0

I have cleared node_modules and performed all the mentioned steps.

Error message here.

WebSocket connection to 'ws://localhost:3000/ws' failed:

If I use port 3000 the error disappears, but nothing works.

Environment

System: OS: Windows 10 10.0.19044 CPU: (16) x64 AMD Ryzen 7 3700X 8-Core Processor Binaries: Node: 16.10.0 - C:\Program Files\nodejs\node.EXE Yarn: 1.22.5 - C:\Program Files (x86)\Yarn\bin\yarn.CMD npm: 7.24.0 - C:\Program Files\nodejs\npm.CMD Browsers: Chrome: 96.0.4664.110 Edge: Spartan (44.19041.1266.0), Chromium (96.0.1054.57) Internet Explorer: 11.0.19041.1202 npmPackages: react: 17.0.2 => 17.0.2 react-dom: 17.0.2 => 17.0.2 react-scripts: 5.0.0 => 5.0.0 npmGlobalPackages: create-react-app: Not Found

Steps to reproduce

  1. Clone repo - https://github.com/Fosol/bug-hot-reload
  2. Run command docker-compose up -d
  3. Open browser http://localhost:5000

Expected behavior

Application should work and hot reload should work.

Actual behavior

Application doesn’t work and hot reload doesn’t work. Additionally, it requires rebuilding the image to get any changes. A refresh doesn’t work.

Reproducible demo

Repo here - https://github.com/Fosol/bug-hot-reload

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 42
  • Comments: 70 (4 by maintainers)

Commits related to this issue

Most upvoted comments

I was able to work around this issue by manually specifying the port used in my .env file:

WDS_SOCKET_PORT=443

See https://create-react-app.dev/docs/advanced-configuration/#:~:text=for more details.-,WDS_SOCKET_PORT,-✅ Used

WDS_SOCKET_PORT=0 Will use window location, still think its a misconfig in CRA but I’ll check history in wds server to look for other clues

In my case, I am using http-proxy-middleware, I tried to add WDS_SOCKET_PORT=0 or WDS_SOCKET_PORT=443 to .env, but it is still not working.

Herer is my solution, I updated the proxy configuration from:

    app.use(
        '/hubs',
        createProxyMiddleware({
            target: 'your target url',
            changeOrigin: true,
            ws: true
        })
    );

to

   app.use(
        createProxyMiddleware('/hubs', {
            target: 'your target url',
            changeOrigin: true,
            ws: true
        })
    );

Then the issue is fixed.

I have the same problem. I upgraded my react-scripts from v4 to v5 and I lost hot reload.

Here’s my tech stack:

  • Ubuntu
  • Nginx
  • Docker
  • React
  • mkcert

I use mkcert to create valid local certificates. Then instead of localhost:3000, I use hosts file to create a DNS record for my project. Thus I develop using https://project.local domain.

And I use nginx as a reverse proxy and here’s my nginx config file:

server {
    listen 80;
    server_name project.local;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    server_name project.local;

    ssl_certificate /Temp/Project/AdminPanel/Certificate.pem;
    ssl_certificate_key /Temp/Project/AdminPanel/Key.pem;

    error_page 502 /502.html;

    location /502 {
    	root /Temp/Project/AdminPanel/Nginx;
    	internal;
    }

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
    }
}

It was working great. But when I upgraded my react-scripts from v4 to v5, it now complains that:

WebSocketClient.js:13 WebSocket connection to 'wss://project.local:3000/ws' failed:    
WebSocketClient	@	WebSocketClient.js:13   
initSocket	@	socket.js:17   
(anonymous)	@	socket.js:38   

What should I change to fix this?

Hi. I am using ASP.NET 6 with React 17 and no workaround described above works for me. WebSocket connection to 'wss://localhost:58641/ws failed. However, the backend was expecting /sockjs-node instead of /ws path. Setting WDS_SOCKET_PATH variable to sockjs-node causes the error disappear, but hot reload still doesn’t work.

Any update for the issue?

First, I am using NodeJS 18, React 18. I develop by running react-script start. But I also tried using nginx.

I added location /ws in nginx configuration and WDS_SOCKET_PATH=0 in docker-compos file. It helped me.

P.S. I’m Ukrainian, I didn’t translate it myself, sorry if I made a mistake somewhere)

for me adding

WDS_SOCKET_HOST=0.0.0.0
WDS_SOCKET_PORT=0

to the .env file is what fixed it

I’m using asp.net core 5 as my backend, I have the same message when I try to proxy my react app. The issue appeared after I’ve been upgrading packages to react 17.0.2 and react-router-dom to v6, not sure which caused it. (also noticed that every build is using different port for wss connection)

I’d love to know any solution to that

Now there is no connection error with WDS_SOCKET_PORT=0, but hot reload still doesn’t work for me. I’m running app in docker container (port 3050) and using nginx.

Nginx default.conf:

    upstream client {
        server client:3000;
    }
    upstream api {
        server api:3001;
    }

    server {
        listen 80;
    
        location / {
            proxy_pass http://client;
        }
    
        location /ws {
            proxy_pass http://client;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            proxy_set_header Host $host;
        }
    
        location /api {
            rewrite /api/(.*) /$1 break;
            proxy_pass http://api;
        }
    }

docker-compose.yml:

version: '3.8'
services:
  nginx:
    depends_on:
      - api
      - client
    restart: always
    build:
      dockerfile: Dockerfile
      context: ./nginx
    ports:
      - '3050:80'
client:
    stdin_open: true
    environment:
      - CHOKIDAR_USEPOLLING=true
      - WDS_SOCKET_PORT=0
    build:
      dockerfile: Dockerfile
      context: ./client
    volumes:
      - ./client/src:/app/src

Can anyone help?

@raix, WDS_SOCKET_PORT=0 worked for me. But we still need it to be the default value and automatic. Because it’s very repetitive to add this config to every .env file of all projects.

However, you saved us for now. Thank you so much.

With WDS_SOCKET_PORT=0 the websocket connection and hot reload is working again on ASP.Net Core 6 on Windows 10.

The suggestion workarounds do not work when the webpack-dev-server is behind a proxy which uses https. There does not seem to be a way to set the “scheme” to wss.

A very easy solution would be to also expose https://webpack.js.org/configuration/dev-server/#websocketurl in the react-scripts configuration (similar to the other WDS_ variables at https://github.com/facebook/create-react-app/blob/20edab4894b301f6b90dad0f90a2f82c52a7ac66/packages/react-scripts/config/webpackDevServer.config.js#L20-L22).

For me, also in development the c-r-a app runs on https to avoid suprises with service workers and other things which behave differently when used secure.

To get protocol/hostname/port from browser one could then use auto://0.0.0.0:0/ws.

Update

With

WDS_SOCKET_HOST=0.0.0.0
WDS_SOCKET_PORT=0

does get all values from the browser and magically also switches to wss scheme when https is in use. So no action required.

For me it seemed that just adding

WDS_SOCKET_PORT=0

to me .env file was enough.

I still believe it’s a bug because it should default to the port of the current window.location for ws connection.

From what I’ve seen, @sylvainDNS is correct in his comment: webpack-dev-server does not respect PUBLIC_URL when starting the hot refresh socket. In proxied environments (e.g. multi-frontend with Traefik in front, routing on sub-URLs) it’s not possible to just redirect /ws to a frontend, since there might be several frontends in simultaneous development.

While we are waiting for a solution, I’ve fell back to craco. Yes, craco is officially not supported for CRA 5.x and Webpack 5, however, it still works quite well for rewriting webpack-dev-server’s configuration. I’ve made it work with the following configuration:

module.exports = {
    devServer: devServerConfig => {
        devServerConfig.webSocketServer = {
            options: { path: process.env.PUBLIC_URL + 'ws' }
        };

        return devServerConfig;
    }
};

Hope this helps.

I had the same problem after upgrading react-scripts from v4 to v5. Adding WDS_SOCKET_PORT=0 to the environment did solve the issue.

Definitely a bug that needs fixing or thorough documentation. It’s a minimum a breaking change…

If you change the default port from 5000 to 3000 the error goes away, but the site doesn’t work at all. Even manual refreshing the page doesn’t work. You have to rebuild the container for it to get any changes.

I added this in my .env file and it solved the problem.

WDS_SOCKET_PORT=0

give it a try.

@raix did you ever find the correct fix? It’d be good to have an authoritative answer.

Same issue with identical packages, but error message is

WebSocketClient.js:16 WebSocket connection to 'ws://localhost:3084/ws' failed: Invalid frame header

so the connection itself seems to be established and I can see in network tab in Chrome selecting request to “ws”

{"type":"hot"}
{"type":"liveReload"}
{"type":"reconnect","data":10}
{"type":"overlay","data":{"errors":true,"warnings":false}}
{"type":"hash","data":"89c4f09f2b82addd303a"}
{"type":"ok"}
Invalid frame header

Connection is established via dev server and http-proxy-middleware configured as follows

const {createProxyMiddleware} = require('http-proxy-middleware');

module.exports = app => {
  app.use(
    ['/api/**', '/ui'],
    createProxyMiddleware({
      target: 'http://localhost:8084', 
      ws: true,
      changeOrigin: true,
      cookieDomainRewrite: 'localhost:3084',
      cookiePathRewrite: '/', 
    })
  );
};

The identical configuration is working with react-scripts 4.0.3.

I am experiencing the same issue on my current project and I found a workaround.

In my dev env, I’m using a CRA in a docker context, with Traefik as a reverse proxy. There is 2 apps : a legacy Angular app, and a React app. Traefik redirects traffic in accordance with path prefix : v2 to React app, Angular otherwise : react-scripts 4.x diagram

Here how I handled it in react-scripts 4.x :

  • I defined the path prefix in my React app using the homepage: "v2" field in the package.json.
  • In Traefik, I put a rule to redirect prefixed urls to React.
  • To work with Webpack Dev Server & hot reloading, I set an env var : WDS_SOCKET_PATH=/v2/sockjs-node

With react-scripts 5.0.0, I need to do two changes:

  • Specify an other env var : WDS_SOCKET_PORT=0 because the React app no longer uses the default app port (80 thanks to Traefik): it was trying to access websocket through the port 3000.
  • Add a new Traefik rule redirecting all trafic on /ws path to the React App and remove WDS_SOCKET_PATH env var to use default value (/ws).
    I think it is due to an issue introduced in 5.0.0 : DevServer WS does not use the specified path prefix in package.json. This can be very annoying if you have several React application using Webpack Dev Server WS. react-scripts 5.0.0 diagram

I can perform additional tests if you want.

For me WDS_SOCKET_PORT can not be set statically. Because we have a system that dynamically assigns a port to our Nginx reverse proxy to bind to docker’s 3000.

I had this extremely annoying issue and could not figure it out, but what was causing this for me was a local extension I had installed in chrome. My guess is having two webpack-dev-servers running causes an issue. Anyone know how to resolve this without ejecting?

2 years of discussion for a very simple answer. We nerds are strange brew.

WDS_SOCKET_PORT=0

Simple Simon

I had this extremely annoying issue and could not figure it out, but what was causing this for me was a local extension I had installed in chrome. My guess is having two webpack-dev-servers running causes an issue. Anyone know how to resolve this without ejecting?

Tell me if its working

I’ve found that “Google Docs Offline” extension is a common culprit. Turning it off worked for me.

@Vanshii21 yes, this did work! Thank you! 👍

I solved it just by removing node modules from my file then install it again… Surely there is an difficulty in node modules… as you find rm -node modules then then npm install

I’m quite a newbie and I don’t really know that much about how react works with babel and webpack and everything. I was following a docker course on Udemy by Stephen Grider and I decided to try doing something similar to the course material, but with my own customizations. Anyway - I discovered that when I used a different version of the axios library, the 2 fixes: WDS_SOCKET_PORT=0 and nginx default.conf: location /ws { proxy_pass http://client; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection “Upgrade”; } did not work. However when I used the version of axios from the course, it did.

package.json (2 fixes do not work) “dependencies”: { “@testing-library/jest-dom”: “^5.16.4”, “@testing-library/react”: “^13.3.0”, “@testing-library/user-event”: “^13.5.0”, “axios”: “^0.27.2”, “react”: “^18.2.0”, “react-dom”: “^18.2.0”, “react-scripts”: “5.0.1”, “web-vitals”: “^2.1.4” },

package.json (2 fixes do work) “dependencies”: { “@testing-library/jest-dom”: “^5.16.4”, “@testing-library/react”: “^13.3.0”, “@testing-library/user-event”: “^13.5.0”, “react”: “^18.2.0”, “react-dom”: “^18.2.0”, “react-scripts”: “5.0.1”, “web-vitals”: “^2.1.4”, “axios”: “0.18.0” },

Basically what had happened was that I had installed axios independently (running the command npm install axios) in the first case - which caused it not to work. When I re-created the project from scratch and did not run npm install axios in the react folder, but added the dependency “axios”: “0.18.0” in the package.json file it worked fine (with the WDS_SOCKET_PORT=0 as well as nginx default.conf location /ws fixes).

I couldn’t manage to fix the first case - even by running npm uninstall axios or changing the package.json file to “axios”: “0.18.0”. I think this is because installing axios independently may have changed other random packages too (because when I do a diff of the package-lock.json files (in the case that worked and the case that didn’t), there are some differences in “node_modules/@babel/code-frame”: and other @babel things. I don’t really understand this - I assume it is because a different version of axios requires different other dependencies, which mean that the fixes don’t work. Basically - the message is, it might be a node_modules or dependencies issue and getting the correct set of dependencies may be key. Hope this helps someone.

Since my website is in a reverse proxy adding

WDS_SOCKET_PORT=0

to .env didn’t work.

I needed to instead pass

WDS_SOCKET_PORT=443

I figured it out because trying to go to https://my.domain:3000/ws gave me a could not connect, but https://my.domain:443/ws worked.

I was facing the same issue, but with WDS_SOCKET_PORT=0 it worked for me. No web socket error in the console anymore and hot reload also working.

My default.conf currently looks like this:

upstream frontend {
    server client:3000;
}

upstream backend {
    server api:5000;
}

server {
    listen 80;

    location / {
        proxy_pass http://frontend;
    }

    location /ws {
        proxy_pass http://frontend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    location /api {
        rewrite /api/(.*) /$1 break;
        proxy_pass http://backend;
    }
}

My docker-compose file looks like this:

version: '3'
services:
    client:
        build:
            dockerfile: Dockerfile.dev
            context: ./client
        volumes:
            - /app/node_modules
            - ./client:/app
        environment:
#            Fixes bug where websocket connection is fixed to default port 3000
            - WDS_SOCKET_PORT=0
... other services