Invalid WebSocket frame: RSV1 must be clearについての調査ログ
macOSで開発を行っていると遭遇した「RangeError: Invalid WebSocket frame: RSV1 must be clear」エラーについて調査した際のログ。
- # エラーを見る
- # ポートを使用しているプロセスを見る
- # 同様の事例
- # 原因だと思われる事象
- # 解決案
ある日、macOSで開発を行っていると「RangeError: Invalid WebSocket frame: RSV1 must be clear」エラーが表示され、HMRが動作しなくなる事象に遭遇した。
最初は簡単な問題だと思い特に調べずに対応を行ったが、調査が必要になったため、その内容を残す。根本的な解決はしていない。
エラーを見る
次のようなエラーが出力されていた。このエラーはサーバーを立ち上げて直ぐに発生するわけではなく、しばらく経過してから発生し、発生するとHMRが動作しなくなる。
$ vite
➜ Local: http://localhost:8080/
00:00:00 [vite] ws error:
RangeError: Invalid WebSocket frame: RSV1 must be clear
エラー自体は非常に分かりやすい。viteが内部的に利用しているNode.jsのWebSocket実装として有名なws
でエラーが発生しており、WebSocketがやりとりするデータの形式であるフレームが無効であることを示している。
無効である理由は、エラーからWebSocketのフレームのヘッダの一部であるRSV1がクリア、つまり0でないにも関わらず、圧縮メッセージをサポートしていないクライアントに対して送信しているためだと思われる。RSV1は、圧縮メッセージに対して利用される。
https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#format
ポートを使用しているプロセスを見る
何らかのプロセスが、8080ポートを使用している可能性を考えた。
$ lsof -i:8080
コマンドを実行したが、8080ポートを使用しているプロセスは見つからなかった。
同様の事例
同様の事例がないか調べると、同じエラーを報告しているIssueが複数見つかった。いずれもmacOSかつ8080ポートを利用しているケースで発生している。
- https://github.com/vitejs/vite/issues/15688
- https://github.com/webpack/webpack-dev-server/issues/5018
- https://github.com/websockets/ws/issues/2109
- https://github.com/websockets/ws/issues/2169
原因だと思われる事象
同様の事例を報告しているIssueでも言及されているが、macOSの問題である可能性が高い。 macOSのペアレンタルコントロールなどが8080ポートを乗っ取ってしまう問題が報告されている。
https://discussions.apple.com/thread/250500940
https://developer.apple.com/forums/thread/654362
解決案
どのIssueでも最終的にmacOSでは8080ポートを使うな、または別のポートを使えという提示がされている。
wsパッケージを直接利用している場合はクラッシュしないようにすれば良いように思うが、viteやwebpackなどで間接的に利用している場合は対応が難しいと思われる。
現状では、次のような解決案しか考えられない。
- ポートを占有している機能が分かり、問題がなければ無効化する。
- 利用するポートを変更する。
- 修正されている可能性に掛けて、macOSをアップデートする。
- Linuxを使う。