Skip to content

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サーバーにおける ~ プレフィックス付きパスの展開

🚩 重要な補足と適用条件

動作環境の注意

この解決策は以下の環境で特に有効です:

  1. Windows(PowerShell/Win32-OpenSSH)
  2. カスタムSSHポートを使用するサーバー
  3. 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が効果ない場合)

  1. SFTPコマンドでの代替転送:

    bash
    sftp -P 29418 michealvern.genzola@192.168.0.122
    get hooks/commit-msg jyei-erp/.git/hooks/
  2. SSH接続での直接実行:

    bash
    ssh -p 29418 michealvern.genzola@192.168.0.122 \
        "cat hooks/commit-msg" > jyei-erp/.git/hooks/commit-msg

最終的な推奨対応

  1. 常に -O オプション付きでscp実行
    → ほぼ全てのケースで即時解決
  2. 永続化が必要なら ~/.ssh/config に設定追加:
    bash
    Host 192.168.0.122
        Option +scp
        Port 29418
  3. サーバー管理者なら sshd_configSubsystem 設定見直し

この対策はLinux/Windows/macOS環境全てで有効であり、リモートサーバーの設定変更権限がないユーザーでも適用可能です。