Skip to main content
Version: 3.x

Troubleshooting connection issues

First and foremost, please note that disconnections are common and expected, even on a stable Internet connection:

  • anything between the user and the Socket.IO server may encounter a temporary failure or be restarted
  • the server itself may be killed as part of an autoscaling policy
  • the user may lose connection or switch from WiFi to 4G, in case of a mobile browser
  • the browser itself may freeze an inactive tab
  • ...

That being said, the Socket.IO client will always try to reconnect, unless specifically told otherwise.

Let's review how you can troubleshoot a connection failure.

In Node.js

Listening to the connect_error event

const socket = require("socket.io-client")("https://example.com");

socket.on("connect_error", (err) => {
console.log(`connect_error due to ${err.message}`);
});

Common errors:

  • the server might not be reachable

Please make sure the Socket.IO server is actually reachable at the given URL. You can test it with:

curl "https://example.com/socket.io/?EIO=4&transport=polling"

which should return something like this:

0{"sid":"Lbo5JLzTotvW3g2LAAAA","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":5000}

If that's not the case, please check that the Socket.IO server is running, and that there is nothing in between that prevents the connection.

  • there might be an issue with the SSL certificate of the server

You can test it with rejectUnauthorized set to false.

const socket = require("socket.io-client")("https://example.com", {
rejectUnauthorized: false // WARN: please do not do this in production
});

If that works, it could mean that the SSL certificate is invalid, or, if you are using a self-signed certificate, that you have to trust it on the client-side:

const socket = require("socket.io-client")("https://example.com", {
ca: fs.readFileSync('./cert.pem')
});

Debug logs

As explained here, you can also enable the logs to see what's going on under the hood.

For reference, here are the logs for a successful connection:

$ DEBUG=socket* node index.js

socket.io-client:url parse https://example.com +0ms
socket.io-client new io instance for https://example.com +0ms
socket.io-client:manager readyState closed +0ms
socket.io-client:manager opening https://example.com +0ms
socket.io-client:manager connect attempt will timeout after 20000 +7ms
socket.io-client:manager readyState opening +1ms
socket.io-client:manager open +6ms
socket.io-client:manager cleanup +0ms
socket.io-client:socket transport is open - connecting +0ms
socket.io-client:manager writing packet {"type":0,"nsp":"/"} +1ms
socket.io-parser encoding packet {"type":0,"nsp":"/"} +0ms
socket.io-parser encoded {"type":0,"nsp":"/"} as 0 +0ms
socket.io-parser decoded 0{"sid":"emVyzJPFYLlVMB7YAAAD"} as {"type":0,"nsp":"/","data":{"sid":"emVyzJPFYLlVMB7YAAAD"}} +2ms
socket.io-client:socket socket connected with id emVyzJPFYLlVMB7YAAAD +2ms

In the browser

In the Network Monitor of your browser

In most cases, you should see something like this:

Network monitor upon success

  1. the Engine.IO handshake (contains the session ID — here, zBjrh...AAAK — that is used in subsequent requests)
  2. the Socket.IO handshake request (contains the value of the auth option)
  3. the Socket.IO handshake response (contains the Socket#id)
  4. the WebSocket connection
  5. the first HTTP long-polling request, which is closed once the WebSocket connection is established

The Socket.IO server may return the following HTTP status:

In case of an HTTP 400 response, the response payload will be one of the following:

  • {"code":0,"message":"Transport unknown"}

The transport query parameter is missing or invalid.

To reproduce: curl "<url>/socket.io/" or curl "<url>/socket.io/?transport=udp"

  • {"code":1,"message":"Session ID unknown"}

The session ID (included in the sid query parameter) is unknown from the server. That may happen in a multi-server setup.

To reproduce: curl "<url>/socket.io/?transport=polling&sid=1234"

  • {"code":2,"message":"Bad handshake method"}

The initial request must be a GET request.

To reproduce: curl -X PUT "<url>/socket.io/?transport=polling"

  • {"code":3,"message":"Bad request"}

An error has occurred during the handshake process.

This error cannot be easily reproduced with a single curl command.

  • {"code":4,"message":"Forbidden"}

The request was denied in the allowRequest handler.

To reproduce:

const io = require("socket.io")(httpServer, {
allowRequest: (req, callback) => {
callback(null, false);
}
});
  • {"code":5,"message":"Unsupported protocol version"}

The protocol version is not supported by the server. Support for Socket.IO v2 clients must be explicitly enabled with the allowEIO3 option:

const io = require("socket.io")(httpServer, {
allowEIO3: true // false by default
});

To reproduce: curl "<url>/socket.io/?transport=polling&EIO=3"

Another quite common error is:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at ...

Which probably means that you have to enable Cross-Origin Resource Sharing (CORS) on the server-side. Please see the documentation here.