You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Websocket RangeError: Invalid WebSocket frame: RSV2 and RSV3 must be clear #1354
[ x] I've searched for any related issues and avoided creating a duplicate issue.
Description
I'm using ws as a client in my node application, and when I attempt to connect to the host, the connection is closed with the error 'Websocket RangeError: Invalid WebSocket frame: RSV2 and RSV3 must be clear'.
It is worth noting that the connection is successful to a different host, but I believe this is a client issue?
It's also worth noting that faye-websocket functions correctly in the same situation.
Reproducible in:
version: 5.1.1
Node.js version(s): 8.9.4
OS version(s): Windows 7 Professional v6.1 (build 7601)
Steps to reproduce:
Run the following code inside of a Node Application:
It might be a bug that has been recently fixed in nodejs/node#17806 but I think not yet backported to Node.js 8.
Try to use Node.js 9. If the issue persists please post the received data on the socket. You can do that by attaching a listener for the 'data' event on the internal socket.
As of today, electron is currently running node@8.9.3 in it's main process. So the solution of upgrading the local node version is not a viable option for electron app developers.
FWIW I'm hitting the same issue with Node 10 too, but I would expect that this is a server-side issue, with a server sending a frame with those flags that should actually not be set.
I am experiencing a similar issue on node v8.11.3 and v10.6.0
node_modules/ws/lib/receiver.js:167
return error(RangeError, 'RSV1 must be clear', true, 1002);
^
RangeError: Invalid WebSocket frame: RSV1 must be clear
at Receiver.getInfo (/node_modules/ws/lib/receiver.js:167:14)
at Receiver.startLoop (/node_modules/ws/lib/receiver.js:121:22)
at Receiver._write (/node_modules/ws/lib/receiver.js:69:10)
at doWrite (_stream_writable.js:397:12)
at writeOrBuffer (_stream_writable.js:383:5)
at Receiver.Writable.write (_stream_writable.js:290:11)
at TLSSocket.socketOnData (/node_modules/ws/lib/websocket.js:795:35)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)
at TLSSocket.Readable.push (_stream_readable.js:208:10)
at TLSWrap.onread (net.js:597:20)
Have wrapped ws.send() in a try / catch as well as set perMessageDeflate=false in the client constructor options.
@lpinca thank you for the fast response. This advice was most helpful, the error is on the client and I added the listener as you suggested.
This led me to find what I think could be the cause. The server (which also uses ws) is aborting the handshake based on a certain condition (a custom override in our app) using a copy of the abortHandshake function.
And so it is writing the following data to the socket:
This worked fine sending JSON payloads. I'm testing a C client with binary payloads which crash the server.
C:\Public\NodeJS_WS>node app.js
events.js:292
throw er; // Unhandled 'error' event
^
RangeError: Invalid WebSocket frame: RSV2 and RSV3 must be clear
at Receiver.getInfo (C:\Public\NodeJS_WS\node_modules\←[4mws←[24m\lib\receiver.js:171:14)
at Receiver.startLoop (C:\Public\NodeJS_WS\node_modules\←[4mws←[24m\lib\receiver.js:131:22)
at Receiver._write (C:\Public\NodeJS_WS\node_modules\←[4mws←[24m\lib\receiver.js:78:10)
←[90m at writeOrBuffer (internal/streams/writable.js:358:12)←[39m
←[90m at Receiver.Writable.write (internal/streams/writable.js:303:10)←[39m
at Socket.socketOnData (C:\Public\NodeJS_WS\node_modules\←[4mws←[24m\lib\websocket.js:900:35)
←[90m at Socket.emit (events.js:315:20)←[39m
←[90m at addChunk (internal/streams/readable.js:309:12)←[39m
←[90m at readableAddChunk (internal/streams/readable.js:284:9)←[39m
←[90m at Socket.Readable.push (internal/streams/readable.js:223:10)←[39m
Emitted 'error' event on WebSocket instance at:
at Receiver.receiverOnError (C:\Public\NodeJS_WS\node_modules\←[4mws←[24m\lib\websocket.js:805:13)
←[90m at Receiver.emit (events.js:315:20)←[39m
←[90m at emitErrorNT (internal/streams/destroy.js:106:8)←[39m
←[90m at emitErrorCloseNT (internal/streams/destroy.js:74:3)←[39m
←[90m at processTicksAndRejections (internal/process/task_queues.js:80:21)←[39m {
[←[32mSymbol(status-code)←[39m]: ←[33m1002←[39m
}
C:\Public\NodeJS_WS>node --version
v14.15.4
Also reproduced initially on WSL2.
RangeError: Invalid WebSocket frame: RSV2 and RSV3 must be clear
at Receiver.getInfo (/home/tgraupmann/NodeJS_WS/node_modules/ws/lib/receiver.js:171:14)
at Receiver.startLoop (/home/tgraupmann/NodeJS_WS/node_modules/ws/lib/receiver.js:131:22)
at Receiver._write (/home/tgraupmann/NodeJS_WS/node_modules/ws/lib/receiver.js:78:10)
at doWrite (_stream_writable.js:415:12)
at writeOrBuffer (_stream_writable.js:399:5)
at Receiver.Writable.write (_stream_writable.js:299:11)
at Socket.socketOnData (/home/tgraupmann/NodeJS_WS/node_modules/ws/lib/websocket.js:900:35)
at Socket.emit (events.js:198:13)
at addChunk (_stream_readable.js:288:12)
at readableAddChunk (_stream_readable.js:269:11)
Emitted 'error' event at:
at Receiver.receiverOnError (/home/tgraupmann/NodeJS_WS/node_modules/ws/lib/websocket.js:805:13)
at Receiver.emit (events.js:198:13)
at errorOrDestroy (internal/streams/destroy.js:107:12)
at onwriteError (_stream_writable.js:430:5)
at onwrite (_stream_writable.js:461:5)
at Receiver.startLoop (/home/tgraupmann/NodeJS_WS/node_modules/ws/lib/receiver.js:152:5)
at Receiver._write (/home/tgraupmann/NodeJS_WS/node_modules/ws/lib/receiver.js:78:10)
[... lines matching original stack trace ...]
at Receiver.Writable.write (_stream_writable.js:299:11)
tgraupmann@polaris:~/NodeJS_WS$ node --version
v10.19.0
The offending C client code looks like this:
_libwsclient_write(_sWebSocketClient, refFrame._mData, FChromaStreamRefFrame_DATA_SIZE);
The buffer is a simple unsigned char* and I'm passing the size.
It's entirely that I'm using the websocket API incorrectly, and will take any recommendations for a better client that handles binary payloads in pure "C".
That said, it's still able to crash the server though its incorrect use.
I also have a direct repro for any that are interested in following up.
I'm seeing this in node v18.8.0 when connecting from a Safari client (latest Safari, latest iOS 16.3). Hard to reproduce: it does not happen on first connect, but after reloading the page. Yet after a couple of reloads it works, then breaks again.
Sorry could not provide more details right now. Weird bug...don't even know if it comes from the ws library, just posting here because I found this issue while searching for answers
More details
It's probably been covered in this issue or elsewhere in ws already but I went looking around and it seems:
MUST be 0 unless an extension is negotiated that defines meanings for non-zero values. If a nonzero value is received and none of the negotiated extensions defines the meaning of such a nonzero value, the receiving endpoint MUST Fail the WebSocket Connection.
So, at least in my case, the Safari client seems to be incorrectly (?) setting these bits.
It may the wrong fit for ws (and there may be valid security concerns around not doing this), but a possible guide here might be the robustness principle: "be conservative in what you send, be liberal in what you accept"
If that could be possible, then adding a ws API (maybe in the form of an optional strictProtocol flag), like:
the receiving endpoint MUST Fail the WebSocket Connection.
I'm strongly against adding a strictProtocol option or anything like that. A lot of WebSocket implementation do not even inform the user of the error. They just close the connection silently.
Also, it is not the first time that Safari introduces bugs like this. See #1922.
Understood @lpinca I know you don't want to dirty this library with irregularities or tolerances of those. Thank you for your consideration of this idea, it sounds like you've given this some serious thought and like you believe it's the right choice to not include here because doing so would mean your library would no longer meet the standard of quality you're trying to keep. I trust you. Thank you for your information--including on the other bug (how interesting! that Safari!)--and thanks for the amazing work on this great library!
I have set proper error handler on the websocket wss.on('connection', function(ws) { ws.on('error', console.error); });
I experience that in some cases I see the log, but in rear cases
(Probably ws error handler not working properly or removed?) it does not catch the error and node process exits and it kills my app.
running ws version: 8.11.0 & node16
@lpinca can you help me with few hints.
Where should I start to search the root cause of the issue?
Thanks..
node:events:491
throw er; // Unhandled 'error' event
^
RangeError: Invalid WebSocket frame: RSV2 and RSV3 must be clear
at Receiver.getInfo (/opt/my/src/node_modules/ws/lib/receiver.js:176:14)
at Receiver.startLoop (/opt/my/src/node_modules/ws/lib/receiver.js:136:22)
at Receiver._write (/opt/my/node_modules/ws/lib/receiver.js:83:10)
at writeOrBuffer (node:internal/streams/writable:391:12)
at _write (node:internal/streams/writable:332:10)
at Receiver.Writable.write (node:internal/streams/writable:336:10)
at TLSSocket.socketOnData (/opt/my/src/node_modules/ws/lib/websocket.js:1272:35)
at TLSSocket.emit (node:events:513:28)
at TLSSocket.emit (node:domain:489:12)
at addChunk (node:internal/streams/readable:315:12)
Emitted 'error' event on WebSocket instance at:
at Receiver.receiverOnError (/opt/my/src/node_modules/ws/lib/websocket.js:1158:13)
at Receiver.emit (node:events:513:28)
at Receiver.emit (node:domain:489:12)
at emitErrorNT (node:internal/streams/destroy:157:8)
at emitErrorCloseNT (node:internal/streams/destroy:122:3)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
code: 'WS_ERR_UNEXPECTED_RSV_2_3',
[Symbol(status-code)]: 1002
}
I was also struggling with such an issue for some time. Tried several different web socket clients, and always the same. Then I started breaking down my code, and it turned out that the following line was causing the issue in my case: request.socket.setEncoding("utf8"); request comes from here:
Using node as a program to use ws, will inconsistent time between the user and server in the same time zone result in the issue of RSV2 and RSV3 must be clear?
The node service on my end is installed using the Docker method
Activity
lpinca commentedon Apr 6, 2018
It might be a bug that has been recently fixed in nodejs/node#17806 but I think not yet backported to Node.js 8.
Try to use Node.js 9. If the issue persists please post the received data on the socket. You can do that by attaching a listener for the
'data'event on the internal socket.lpinca commentedon Apr 10, 2018
@ztnark any update?
jeroenvollenbrock commentedon Apr 11, 2018
Should be resolved in the next Node.js 8 version as well, presumably 8.11.2 :)
ztnark commentedon Apr 11, 2018
ztnark commentedon Apr 12, 2018
@lpinca, good news. I can confirm that upgrading to Node.js 9 (11.1) fixes this issue. I can also test on 8.11.2, when released. Thank you.
lpinca commentedon Apr 13, 2018
I'm closing then. Please reopen if the issue persists.
Thank you.
Set minimum version to node 8.11.2
Set minimum version to node 8.11.2
Set minimum version to node 8.11.2
danielmurray commentedon Jun 6, 2018
Howdy all,
As of today, electron is currently running node@8.9.3 in it's main process. So the solution of upgrading the local node version is not a viable option for electron app developers.
Dan
Turbo87 commentedon Jul 2, 2018
FWIW I'm hitting the same issue with Node 10 too, but I would expect that this is a server-side issue, with a server sending a frame with those flags that should actually not be set.
ashbrener commentedon Jul 12, 2018
I am experiencing a similar issue on node v8.11.3 and v10.6.0
Have wrapped ws.send() in a try / catch as well as set
perMessageDeflate=falsein the client constructor options.lpinca commentedon Jul 12, 2018
Are you getting it on the client or server? If it is on the server it's possible that a malicious client is sending faulty frames intentionally.
If it's on client instead, you can try to log the received data
ashbrener commentedon Jul 12, 2018
@lpinca thank you for the fast response. This advice was most helpful, the error is on the client and I added the listener as you suggested.
This led me to find what I think could be the cause. The server (which also uses ws) is aborting the handshake based on a certain condition (a custom override in our app) using a copy of the abortHandshake function.
And so it is writing the following data to the socket:
... which the client receives and throws the RangeError on. Does this make sense?
4 remaining items
lpinca commentedon Jul 12, 2018
You probably have your own reasons to do that (overriding
handleUpgrade) but theverifyClientoption can be used for this.tgraupmann commentedon Feb 7, 2021
FYI, this issue still reproduces on both WSL2 and Windows 10 for Node v14.15.4.
I have a sample client that can crash a WS server instantly.
I'm using pretty much the minimal sample - Server: https://github.com/tgraupmann/NodeJS_WS/blob/master/app.js
This worked fine sending JSON payloads. I'm testing a C client with binary payloads which crash the server.
Also reproduced initially on WSL2.
The offending C client code looks like this:
This is the client library that I'm using - https://github.com/tgraupmann/libwsclient
It's entirely that I'm using the websocket API incorrectly, and will take any recommendations for a better client that handles binary payloads in pure "C".
That said, it's still able to crash the server though its incorrect use.
I also have a direct repro for any that are interested in following up.
lpinca commentedon Feb 7, 2021
'error'events must be handled.tgraupmann commentedon Feb 7, 2021
That's all it was. The server just needed an error handler to avoid crashing. And now it logs errors without exiting. Thanks!
crisdosaygo commentedon Oct 23, 2022
I'm seeing this in node v18.8.0 when connecting from a Safari client (latest Safari, latest iOS 16.3). Hard to reproduce: it does not happen on first connect, but after reloading the page. Yet after a couple of reloads it works, then breaks again.
Sorry could not provide more details right now. Weird bug...don't even know if it comes from the ws library, just posting here because I found this issue while searching for answers
More details
It's probably been covered in this issue or elsewhere in ws already but I went looking around and it seems:
So, at least in my case, the Safari client seems to be incorrectly (?) setting these bits.
It may the wrong fit for
ws(and there may be valid security concerns around not doing this), but a possible guide here might be the robustness principle: "be conservative in what you send, be liberal in what you accept"If that could be possible, then adding a
wsAPI (maybe in the form of an optionalstrictProtocolflag), like:to permit these "non-conforming" messages could be a way to still serve clients that make these errors.
crisdosaygo commentedon Oct 23, 2022
@tgraupmann I have an error handler, but my websocket closes after showing this RangeError.
lpinca commentedon Oct 23, 2022
@crisdosyago the spec specifically says that
I'm strongly against adding a
strictProtocoloption or anything like that. A lot ofWebSocketimplementation do not even inform the user of the error. They just close the connection silently.Also, it is not the first time that Safari introduces bugs like this. See #1922.
crisdosaygo commentedon Oct 23, 2022
Understood @lpinca I know you don't want to dirty this library with irregularities or tolerances of those. Thank you for your consideration of this idea, it sounds like you've given this some serious thought and like you believe it's the right choice to not include here because doing so would mean your library would no longer meet the standard of quality you're trying to keep. I trust you. Thank you for your information--including on the other bug (how interesting! that Safari!)--and thanks for the amazing work on this great library!
fix: server crashed if clients send invalid frames
misi commentedon Dec 8, 2022
I have set proper error handler on the websocket
wss.on('connection', function(ws) { ws.on('error', console.error); });I experience that in some cases I see the log, but in rear cases
(Probably
wserror handler not working properly or removed?) it does not catch the error and node process exits and it kills my app.running
wsversion: 8.11.0 & node16@lpinca can you help me with few hints.
Where should I start to search the root cause of the issue?
Thanks..
lpinca commentedon Dec 8, 2022
Yes, make sure that the
'error'event listener is not removed before the'close'event is emitted.misi commentedon Dec 12, 2022
Yes removed error handler in tear down, and it caused it. Thanks!
marcolanaro commentedon Dec 16, 2022
@misi Can you please provide a code example or reference for this use case?
atanasyordanov21 commentedon Jun 19, 2023
I was also struggling with such an issue for some time. Tried several different web socket clients, and always the same. Then I started breaking down my code, and it turned out that the following line was causing the issue in my case:
request.socket.setEncoding("utf8");requestcomes from here:smallCF commentedon Jul 13, 2023
Hello author;
Using node as a program to use ws, will inconsistent time between the user and server in the same time zone result in the issue of RSV2 and RSV3 must be clear?
The node service on my end is installed using the Docker method