トラブルシューティング

SSH の "Broken pipe" と "client_loop: send disconnect":根本から直す対策

Broken pipe は TCP 接続が切れたという意味です ── たいていは NAT によるアイドル切断か、足元でネットワークが変わったため。キープアライブ(ServerAliveInterval / ClientAliveInterval)、ローミングには mosh か安定アドレスでの再接続、そして tmux で作業を守る。

CC Chen Chen· 創業者·2026年6月24日·5 分で読めます

"Broken pipe" / "client_loop: send disconnect" の意味

SSH セッションが切れたのは、その下にある TCP 接続がなくなったからです ── 典型的にはアイドル状態でしばらく放置した後に起きます。packet_write_wait: Broken pipeclient_loop: send disconnect: Broken pipe は、同じ出来事をわずかに違う角度から見たものです:クライアントが、もう存在しない接続にデータを送ろうとしたのです。これは認証やサーバーの問題ではなく、接続の持続性の問題で、典型的な原因が 3 つあります:NAT ルーターがアイドル接続を黙って切る、足元でネットワークが変わる(Wi-Fi ↔ モバイル回線)、そしてどちらかの端での過度なアイドルタイムアウト設定です。

3 つの原因

#原因パターン
1NAT/ルーターのアイドルタイムアウト静かな状態が N 分続くと切れる;入力中は問題なし
2足元でネットワークが変わったWi-Fi の圏外に出る / ネットワークを切り替えると切れる
3設定されたアイドル切断サーバーの ClientAliveInterval/CountMax が静かなセッションを閉じている

対策 1 ── キープアライブ(標準的な解決策)

キープアライブは小さなハートビートパケットを送ることで、NAT テーブルやアイドルタイマーが接続を「静か」だと判断しないようにします。クライアント側(~/.ssh/config):

Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3
# = ping the server every 60s; give up after 3 misses

あるいはサーバー側(/etc/ssh/sshd_config)で設定すれば、モバイルアプリを含むすべてのクライアントをカバーできます:

ClientAliveInterval 60
ClientAliveCountMax 3

どちらか一方を設定すれば、アイドル切断の類いはたいてい完全に止まります。モバイルクライアントは通常、アプリがフォアグラウンドにある間は自前のキープアライブを送ります ── サーバー側の設定は、どんなクライアントでも効く二重の備えです。

対策 2 ── モバイルネットワークはローミングするものと受け入れて備える

スマホが Wi-Fi からモバイル回線に切り替わると、TCP 接続のアドレスが変わります ── 素の SSH ではそれを乗り越えられません。キープアライブをどう設定してもセッションは切れます。選択肢は:

  • mosh ── ローミングを乗り越えるために作られています(UDP、アドレスに依存しない)。サーバーへのインストールが必要;トンネルや SFTP はありません。Mosh vs SSH を参照。
  • 安定したアドレス上での高速再接続 ── モバイルでの現実的な答え:Tailscale を使えば、サーバーはどのネットワーク上でも 1 つの同じアドレスを保つので、再接続はワンタップで済み、何も入力し直す必要がありません。TermAI は Tailscale を内蔵し、元いた場所でセッションを開き直します。
  • サーバー上の tmux/screen ── 接続に何が起きても、あなたの作業は生き残ります:tmux attach で再アタッチすれば、実行中のプロセスはそのままです。上のどちらの選択肢とも完璧に組み合わさります。
安定したアドレス経由でスマホ上に再接続された SSH セッション
モバイルの現実:ネットワークは変わり、素の SSH は切れる。安定した Tailscale アドレス + サーバー上の tmux があれば、切断はワンタップ・損失ゼロの出来事になる。

対策 3 ── そもそも長時間ジョブをセッションに依存させない

切断で長時間実行中のコマンドが死んだなら、長く続く習慣はジョブをターミナルに一切結びつけないことです:tmux の中で実行するか、nohup long_command & を使います。スマホではこれが二重に重要です ── 長い待ち時間の間、OS がアプリをサスペンドするかもしれません。ジョブをデタッチして起動し、罪悪感なくアプリを閉じ、後で確認しましょう。

FAQ

なぜ SSH セッションは数分間操作しないと切れるのですか?
NAT ルーターかアイドルタイマーが静かな接続を切ったのです。クライアント側で ServerAliveInterval 60、またはサーバー側で ClientAliveInterval 60 を設定してください。

SSH は Wi-Fi からモバイル回線への切り替えを乗り越えられますか?
素の SSH では無理です ── アドレスが変わります。mosh(ローミングを乗り越える)を使うか、安定した Tailscale アドレスでワンタップ即時再接続し、サーバー上の tmux で作業を守りましょう。

長時間ジョブが接続と一緒に死なないようにするには?
デタッチして実行します:tmux/screen の中、または nohup で。そうすればジョブはどんな切断よりも長生きします。

クイックファクト

  • 意味:TCP 接続が切れた(たいていアイドルで切られた)、認証/サーバーの障害ではない
  • 標準的な解決策:キープアライブ ── ServerAliveInterval 60(クライアント)または ClientAliveInterval 60(サーバー)
  • ネットワークローミング:素の SSH は乗り越えられない ── mosh、または安定したアドレス + 高速再接続
  • 作業を守る:tmux/nohup でジョブをセッションより長生きさせる
Try TermAI

Free on iOS and Android. 5 AI requests/day on the free tier, plus unlimited SSH/SFTP and built-in Tailscale.

CC
Chen Chen — Founder of TermAI

Writes about mobile DevOps, terminal UX, and the surprising depth of "boring" infrastructure.

Was this useful? ← Back to blog