RocketChat / RocketChat/Rocket.Chat

Windows desktop client gets permanently stuck in SockJS reconnect loop after temporary server outage (/sockjs/info returns 200, but no transport is started)

Open
#41,405 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

type: bug
Dominant language
TypeScript
Stars
46.1k
Forks
13.9k
Avg merge
3d 3h
Merged PRs (30d)
130

Description

Description

The Rocket.Chat Desktop client on Windows can become permanently stuck in the "Reconnecting..." state after a temporary Rocket.Chat server outage.

After the server is fully available again, the affected client repeatedly and successfully requests:

GET /sockjs/info

The server and reverse proxy return HTTP 200 within a few milliseconds. However, the client never follows up with a SockJS transport request such as:

GET /sockjs/<server-id>/<session-id>/websocket

The client can remain in this state for many hours. A renderer reload (Ctrl+R) immediately restores the connection. This appears to be a state-dependent failure between successful processing of the SockJS /info response and creation of the actual WebSocket transport. The issue is intermittent, but it has occurred repeatedly on the same Windows client after network interruptions or server outages.

This may be related to, or a regression of, #21783.


Steps to reproduce

The problem is intermittent and may require multiple attempts.

  1. Start Rocket.Chat Desktop 4.15.3 on Windows 11.
  2. Connect it normally to a Rocket.Chat 8.6.1 workspace.
  3. Leave the client connected for some time.
  4. Make the Rocket.Chat server temporarily unavailable, for example:
    • stop the Rocket.Chat stack, or
    • reboot the Rocket.Chat host.
  5. Keep the server unavailable for approximately 60–90 seconds.
  6. Start the server again and wait until Rocket.Chat is fully operational.
  7. Observe the Windows desktop client.

In the affected state:

  • the UI displays Reconnecting...;
  • the retry counter continues increasing;
  • /sockjs/info repeatedly returns HTTP 200;
  • no /sockjs/<server>/<session>/websocket request is initiated;
  • the client never recovers without reloading the renderer.

Expected behavior

Once the server is available again, the desktop client should:

  1. successfully request /sockjs/info;
  2. create a new SockJS/WebSocket transport;
  3. re-establish the DDP connection;
  4. return to the connected state without user interaction.

A temporary server outage must not require users to press Ctrl+R or restart
the desktop application.


Actual behavior

The client remains indefinitely in the Meteor reconnect loop.

A diagnostic snapshot taken while the problem was active showed:

capturedAt:          2026-07-14T05:19:29.929Z
navigator.onLine:    true
visibilityState:     visible
document.hasFocus(): false

Meteor.status():
  status:       waiting
  connected:    false
  retryCount:   165
  retryTime:    1784006378830.4805

Meteor.connection._stream:
  forcedToDisconnect: false
  lastError:           null
  socket:              null

Therefore:

  • the renderer was running;
  • the browser considered the system online;
  • Meteor was actively scheduling retries;
  • the connection was not intentionally disconnected;
  • no stale socket object existed;
  • no useful error was retained;
  • nevertheless, no new transport was created.
Incident timeline:

All timestamps below are UTC.

2026-07-13 12:18:04

The Rocket.Chat host was intentionally rebooted.

The existing Windows desktop WebSocket ended exactly when the server stopped:

GET /sockjs/742/u10xmwjs/websocket
status:          101
request_time:    45279.546 seconds
client:          Rocket.Chat/4.15.3
platform:        Windows
Electron:        42.5.0
Chromium:        148.0.7778.271
connection end:  2026-07-13T12:18:04Z

A Linux desktop client behind the same public IP also lost its WebSocket at the
same time.

2026-07-13 12:18:38–12:19:32

Rocket.Chat restarted:

12:18:38  Waiting for MongoDB
12:18:53  MongoDB is up - starting Rocket.Chat
12:19:32  Rocket.Chat services started successfully

Other clients were subsequently able to establish new WebSocket connections.

From approximately 2026-07-13 12:20:02

The affected Windows client repeatedly requested:

GET /sockjs/info
HTTP status:             200
upstream status:         200
upstream response time:  approximately 2–4 ms

These successful requests continued throughout the night.

No corresponding request to:

/sockjs/<server-id>/<session-id>/websocket

was received from the affected client.

2026-07-14 05:19:29

The diagnostic snapshot showed:

status:       waiting
connected:    false
retryCount:   165
socket:       null
lastError:    null

2026-07-14 approximately 05:25:44

The renderer reloaded.

Immediately afterwards, the normal initialization requests were made again, including /sockjs/info, user information, roles, permissions, settings, subscriptions and rooms. The client became connected again without any server configuration change.

Server setup information
  • Rocket.Chat Server: 8.6.1
  • Deployment method: Docker Compose
  • Number of Rocket.Chat instances: 1
  • Host operating system: Ubuntu Linux
  • Reverse proxy: nginx 1.24
  • Node.js: 22.22.3
  • MongoDB: 8.2.4
  • MongoDB storage engine: WiredTiger
  • TLS: TLS 1.3
  • HTTP used for /sockjs/info: HTTP/2
  • WebSocket proxy connection: HTTP/1.1 with successful 101 Switching Protocols
  • ROOT_URL: HTTPS URL matching the externally used workspace URL

The nginx WebSocket proxy works normally for other clients and for the affected client after a renderer reload.

Client setup information:
  • Rocket.Chat Desktop: 4.15.3
  • Operating system: Windows 11 Professional
  • Architecture: x64
  • Electron: 42.5.0
  • Chromium: 148.0.7778.271
  • Network connection: Wired Gigabit Ethernet (i211) via VDSL

General Internet and DNS connectivity were working while the client was stuck. The /sockjs/info requests reached nginx and Rocket.Chat successfully.

Control observations

A Linux Rocket.Chat Desktop client was connected through the same:

  • public IPv4 address;
  • router;
  • NAT connection;
  • Internet provider;
  • reverse proxy;
  • Rocket.Chat server.

Its WebSocket was also interrupted by the server reboot, but it recovered after the server became available again. Other clients also established WebSocket connections successfully after the restart. This makes a persistent server outage, nginx WebSocket proxy failure, router failure or ISP failure unlikely.

Relevant server-side observation

The affected client repeatedly completes the SockJS information request:

Client
  -> GET /sockjs/info
nginx
  -> HTTP 200
Rocket.Chat upstream
  -> HTTP 200

But it never proceeds to:

Client
  -> GET /sockjs/<server-id>/<session-id>/websocket

The failure therefore appears to occur after receiving the valid /sockjs/info response but before initiating a SockJS transport.

Workaround

Any action that fully reloads the Rocket.Chat renderer restores the connection:

CTRL+R

Restarting the Rocket.Chat server, nginx, router or Windows network adapter is not required.

Impact

Users can remain disconnected for many hours without realizing that no new messages are being received. The UI continues to show a reconnect state, but automatic reconnection never completes. Most non-technical users do not know that Ctrl+R is required.

This is especially problematic after:

  • scheduled server maintenance;
  • server updates;
  • brief server restarts;
  • network interruptions;
  • temporary DNS or Internet failures.
Possible diagnostic direction

The observations suggest inspecting the Meteor/SockJS reconnect path between:

  1. successful completion of /sockjs/info;
  2. SockJS transport selection;
  3. construction of the WebSocket transport;
  4. assignment of the transport to the Meteor stream.

In the failed state:

Meteor retry scheduler is active
        |
        v
/sockjs/info succeeds
        |
        v
no transport request is created
        |
        v
stream returns to "waiting"

Additional client-side logging around SockJS transport selection and transport construction would likely expose the failing state transition. As a resilience measure, the client could also recreate the entire SockJS/Meteor stream after a configurable number of successful /sockjs/info responses that do not result in a transport connection.

Reproducibility

Intermittent, but repeatedly observed.

The client sometimes reconnects normally after an interruption. In other cases it enters the permanent reconnect loop described above.

Related issue

#21783 — Rocket.chat no longer properly reconnects after outage

The current report adds the following evidence not present in that older issue:

  • Rocket.Chat 8.6.1 and Desktop 4.15.3;
  • Meteor state with retryCount: 165;
  • socket: null;
  • lastError: null;
  • successful /sockjs/info responses over many hours;
  • no subsequent SockJS/WebSocket transport request;
  • immediate recovery after renderer reload;
  • comparison with another desktop client behind the same public IP.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the Meteor/SockJS reconnect path using the successful /sockjs/info request as the first observation point. Trace transport selection, WebSocket transport construction, and assignment to Meteor.connection._stream, comparing successful recovery with the stuck state. Done means the client creates a transport and re-establishes DDP without a renderer reload.

Written by the indexing model from the issue text.

Assessment

Tech stack
electron, typescript
Domain
desktop, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.