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環境全てで有効であり、リモートサーバーの設定変更権限がないユーザーでも適用可能です。