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:

bash
subsystem request failed on channel 0
Connection closed

In SFTP clients:

bash
Error:	Server sent disconnect message
Error:	type 2 (protocol error): "subsystem request failed"
Error:	Could not connect to server

In server logs (/var/log/auth.log or /var/log/secure):

bash
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 found

Why 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:

bash
sudo grep -i subsystem /etc/ssh/sshd_config

Common configurations:

bash
Subsystem sftp /usr/lib/openssh/sftp-server

or:

bash
Subsystem sftp /usr/libexec/openssh/sftp-server

or using internal-sftp:

bash
Subsystem sftp internal-sftp

Step 2: Locate the sftp-server Binary

Find where your sftp-server is installed:

bash
sudo find / -name "sftp-server" 2>/dev/null

Common locations:

bash
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-server

Step 3: Verify Binary Permissions

Ensure the sftp-server binary is executable:

bash
ls -la /usr/lib/openssh/sftp-server

If it exists but isn't executable:

bash
sudo chmod +x /usr/lib/openssh/sftp-server

Step 4: Update the Subsystem Path

Edit /etc/ssh/sshd_config with the correct path:

bash
sudo nano /etc/ssh/sshd_config

Find or add the Subsystem line with the correct path:

bash
Subsystem sftp /usr/lib/openssh/sftp-server

The internal-sftp is often more reliable as it's built into sshd:

bash
Subsystem sftp internal-sftp

This 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:

bash
sudo grep -n "Subsystem" /etc/ssh/sshd_config

If you see multiple lines, keep only one:

bash
# Remove duplicate lines, keep only:
Subsystem sftp internal-sftp

Step 7: Validate Configuration

Test the configuration:

bash
sudo sshd -t

No output means the configuration is valid.

Step 8: Restart SSH Service

Apply the changes:

bash
sudo systemctl restart sshd

Step 9: Test SFTP Connection

Connect using the sftp command:

bash
sftp -v username@localhost

You should see:

bash
Connected to localhost.
sftp>

Verify the Fix

List remote files to confirm SFTP works:

bash
echo "ls" | sftp username@localhost

Test 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:

bash
sudo tail -20 /var/log/auth.log | grep sftp

You 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.