O hirunewani blog

Invalid WebSocket frame: RSV1 must be clearについての調査ログ

Created at

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ポートを利用しているケースで発生している。

原因だと思われる事象

同様の事例を報告している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を使う。