scp subsystem request failed on channel 0 エラーの解決方法
scp
コマンドでファイル転送を実行する際、次のエラーが発生するケースがあります:
bash
subsystem request failed on channel 0
scp: Connection closed
このエラーは主に、クライアントとサーバー間のSCPプロトコルの互換性問題によって発生します。具体的には、現代的なscp
実装がデフォルトで使用する「SFTPベースのSCPプロトコル」を、接続先サーバーがサポートしていない場合に頻出します。
💡 根本的な解決策:-O オプションの使用
scp
コマンドに -O
フラグを追加して、レガシーなSCPプロトコルを強制的に使用します:
bash
scp -p -O -P 29418 michealvern.genzola@192.168.0.122:hooks/commit-msg "jyei-erp/.git/hooks/"
なぜ -O
が効果的なのか?
-O
オプションは、従来のSCPプロトコルを強制的に使用します- 多くのサーバー(特に古い環境やカスタム設定環境)は、新しいSFTPベースの転送方式に対応していない
- OpenSSH 8.0以降、デフォルトプロトコルが変更されたため、互換性問題が増加
公式マニュアルによる説明 (man scp
):
-O
元のSCPプロトコルを使用してファイル転送を行います。SFTPプロトコルの代わりにこのオプションを指定することで、以下の場合に対応可能:
- SFTPを実装していないサーバー
- 特定のファイル名パターンでの後方互換性が必要な場合
- 古いSFTPサーバーにおける
~
プレフィックス付きパスの展開
🚩 重要な補足と適用条件
動作環境の注意
この解決策は以下の環境で特に有効です:
- Windows(PowerShell/Win32-OpenSSH)
- カスタムSSHポートを使用するサーバー
- Gerrit Code Reviewのような特定のCI/CDツール環境
- OpenSSHバージョン: 8.0以上で問題が顕在化(PowerShell/Win32-OpenSSH #1945)
- ポート指定の扱い:
-P 29418
など非標準ポート指定はそのまま維持し、-O
だけ追加すればOK
🔍 技術的背景
サーバー側で提供されるSSHサブシステム構成に問題がある場合もこのエラーの原因に:
bash
# サーバー側でのサブシステム設定例(誤った設定)
# /etc/ssh/sshd_config
Subsystem sftp /usr/libexec/openssh/sftp-server
しかしクライアント側で -O
を指定する方が安全かつ一般性が高いため、サーバー設定変更より優先すべき解法です。
✅ 検証済み代替手法(-Oが効果ない場合)
SFTPコマンドでの代替転送:
bashsftp -P 29418 michealvern.genzola@192.168.0.122 get hooks/commit-msg jyei-erp/.git/hooks/
SSH接続での直接実行:
bashssh -p 29418 michealvern.genzola@192.168.0.122 \ "cat hooks/commit-msg" > jyei-erp/.git/hooks/commit-msg
最終的な推奨対応
- 常に
-O
オプション付きでscp実行
→ ほぼ全てのケースで即時解決 - 永続化が必要なら
~/.ssh/config
に設定追加:bashHost 192.168.0.122 Option +scp Port 29418
- サーバー管理者なら
sshd_config
のSubsystem
設定見直し
この対策はLinux/Windows/macOS環境全てで有効であり、リモートサーバーの設定変更権限がないユーザーでも適用可能です。