Invalid handshake error when Socket.IO v4 server receives v3 client connection
0 reputation · 27 Feb 2020, 17:15 UTC
0 reputation · 27 Feb 2020, 17:15 UTC
When a Socket.IO server running major version 4 accepts a connection from a client using major version 3, the handshake process aborts and the server records an error commonly described as "Invalid handshake". The client side emits an error event and the socket disconnects.
The precise goal is to determine which version‑compatibility checks trigger the rejection and whether any server‑side configuration can alter this behavior without forcing version parity.
A Socket.IO v4 server rejects a v3 client because the handshake logic performs a hard-coded major-version comparison before any transport negotiation or middleware runs. The server extracts the client's version from the query parameter v=3.x.x, parses the major component, and compares it against its own major version. If they differ, the handshake is aborted with "Invalid handshake". No server configuration option or documented middleware can bypass this check.
The server reads the v query string sent by the client during the initial HTTP handshake, e.g. v=3.1.4. It then executes logic equivalent to:
const clientMajor = parseInt(clientV.split('.')[0], 10); const serverMajor = parseInt(serverV.split('.')[0], 10); if (clientMajor !== serverMajor) { rejectHandshake(); }This check runs in the Socket.IO handshake layer, before Engine.IO transport selection, CORS evaluation, or any io.use() middleware.
The following options have no effect on the major-version validation:
origins / CORS settingstransports (websocket, polling)pingTimeout, pingIntervalallowEIO3 (controls Engine.IO protocol version, not Socket.IO major version)io.use((socket, next) => ...)All of these are applied after the handshake version check has already terminated the connection.
Socket.IO v4 exposes extension points such as:
io.use() for per-socket authorization (runs after handshake)io.engine.on('connection') for raw Engine.IO sockets (runs after handshake)Neither provides a hook to intercept or override the major-version comparison. The validation is internal to the handshake module and not designed to be extensible.
npm i socket.io@4npm i socket.io-client@3error event followed by disconnection.io.use() middleware or listen on io.engine.on('connection') and confirm they are never invoked for the v3 client.To establish a connection, you must either:
Modifying the library source to disable the check is unsupported and will likely break with future updates due to protocol incompatibilities between major versions.
If you are using a load balancer, proxy, or custom transport layer that might rewrite the v query parameter, confirm the exact query string received by the Socket.IO server. A mismatched or stripped v parameter would produce the same symptom but for a different reason.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.