Skip to content

webpack-dev-server crashes with ECONNRESET when proxying WebSocket /subscription endpoint #8261

@nitishagar

Description

@nitishagar

When running the UI locally with yarn start (webpack-dev-server) pointed at a remote Taskcluster deployment (e.g., community-tc), the dev server crashes shortly after compilation with an unhandled ECONNRESET error:

node:events:486
      throw er; // Unhandled 'error' event
      ^

Error: read ECONNRESET
    at TCP.onStreamRead (node:internal/stream_base_commons:216:20)
Emitted 'error' event on Socket instance at:
    at emitErrorNT (node:internal/streams/destroy:170:8)
    at emitErrorCloseNT (node:internal/streams/destroy:129:3)
    at process.processTicksAndRejections (node:internal/process/task_queues:90:21)

Cause

The /subscription WebSocket proxy in ui/webpack.config.js:91-95 has no error handlers:

"/subscription": {
  ws: true,
  changeOrigin: true,
  target: proxyTarget.replace(/^http(s)?:/, "ws$1:"),
},

When the target rejects the WebSocket connection (e.g., community-tc returning InsufficientScopes for missing web:read-pulse scope), the TCP connection resets. The underlying http-proxy (v1.18.1, via http-proxy-middleware v0.19.1) emits an 'error' event on the socket with no listener attached, which crashes the Node.js process.

This is a known issue with webpack-dev-server 3.x on Node.js 10+.

Fix

Add onError and onProxyReqWs handlers to the /subscription proxy config:

"/subscription": {
  ws: true,
  changeOrigin: true,
  target: proxyTarget.replace(/^http(s)?:/, "ws$1:"),
  onError: function (err, req, res) {
    console.warn('[WS Proxy Error]', err.code, err.message);
  },
  onProxyReqWs: function (proxyReq, req, socket) {
    socket.on('error', function (err) {
      console.warn('[WS Socket Error]', err.code, err.message);
    });
  },
},

Notes

  • This only affects local development (yarn start / webpack-dev-server). Production uses nginx which handles connection resets gracefully.
  • The docker-compose dev mode is also unaffected since it proxies through nginx internally.
  • Reproducible on macOS (arm64) with Node.js v24.x by running TASKCLUSTER_ROOT_URL=https://community-tc.services.mozilla.com yarn start in ui/.
  • Related to Add an indication when the graphql websocket gets closed due to the lack of web:read-pulse scope #8070 -- the same missing-scope scenario triggers both the silent UI failure and this dev server crash.

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