What's Actually Happening
When you try to connect via SFTP or use an SFTP client like FileZilla, WinSCP, or the sftp command, the connection fails because the SSH server's SFTP subsystem is not properly configured. The SSH connection itself works, but the SFTP subsystem cannot start.
The Error You'll See
Using the sftp command:
subsystem request failed on channel 0
Connection closedIn SFTP clients:
Error: Server sent disconnect message
Error: type 2 (protocol error): "subsystem request failed"
Error: Could not connect to serverIn server logs (/var/log/auth.log or /var/log/secure):
sshd[1234]: subsystem request for sftp
sshd[1234]: error: subsystem: cannot stat /usr/lib/openssh/sftp-server: No such file or directory
sshd[1234]: subsystem request for sftp failed, subsystem not foundWhy This Happens
The SFTP subsystem requires:
- A correctly configured Subsystem directive in sshd_config
- The sftp-server binary must exist at the specified path
- The sftp-server binary must be executable
- For internal-sftp, the SSH version must support it
Different Linux distributions place the sftp-server in different locations, and custom SSH installations may have non-standard paths.
Step 1: Check Current Subsystem Configuration
View the current SFTP subsystem setting:
sudo grep -i subsystem /etc/ssh/sshd_configCommon configurations:
Subsystem sftp /usr/lib/openssh/sftp-serveror:
Subsystem sftp /usr/libexec/openssh/sftp-serveror using internal-sftp:
Subsystem sftp internal-sftpStep 2: Locate the sftp-server Binary
Find where your sftp-server is installed:
sudo find / -name "sftp-server" 2>/dev/nullCommon locations:
ls -la /usr/lib/openssh/sftp-server
ls -la /usr/libexec/openssh/sftp-server
ls -la /usr/lib/ssh/sftp-server
ls -la /usr/libexec/ssh/sftp-serverStep 3: Verify Binary Permissions
Ensure the sftp-server binary is executable:
ls -la /usr/lib/openssh/sftp-serverIf it exists but isn't executable:
sudo chmod +x /usr/lib/openssh/sftp-serverStep 4: Update the Subsystem Path
Edit /etc/ssh/sshd_config with the correct path:
sudo nano /etc/ssh/sshd_configFind or add the Subsystem line with the correct path:
Subsystem sftp /usr/lib/openssh/sftp-serverStep 5: Use internal-sftp (Recommended Alternative)
The internal-sftp is often more reliable as it's built into sshd:
Subsystem sftp internal-sftpThis is especially useful for chroot SFTP setups:
``` Subsystem sftp internal-sftp
Match Group sftpusers ChrootDirectory /home/%u ForceCommand internal-sftp AllowTcpForwarding no X11Forwarding no ```
Step 6: Check for Conflicting Subsystem Lines
Multiple Subsystem lines for sftp cause issues:
sudo grep -n "Subsystem" /etc/ssh/sshd_configIf you see multiple lines, keep only one:
# Remove duplicate lines, keep only:
Subsystem sftp internal-sftpStep 7: Validate Configuration
Test the configuration:
sudo sshd -tNo output means the configuration is valid.
Step 8: Restart SSH Service
Apply the changes:
sudo systemctl restart sshdStep 9: Test SFTP Connection
Connect using the sftp command:
sftp -v username@localhostYou should see:
Connected to localhost.
sftp>Verify the Fix
List remote files to confirm SFTP works:
echo "ls" | sftp username@localhostTest file transfer:
```bash # Upload a test file echo "test" > /tmp/testfile.txt sftp username@localhost <<< "put /tmp/testfile.txt"
# Download it back sftp username@localhost <<< "get testfile.txt /tmp/testfile_downloaded.txt"
# Verify cat /tmp/testfile_downloaded.txt ```
Check server logs for successful SFTP session:
sudo tail -20 /var/log/auth.log | grep sftpYou should see successful session logs without subsystem errors.
For production systems, prefer internal-sftp over external sftp-server as it's more reliable and doesn't depend on file paths that vary by distribution.