The SSH daemon (sshd) is refusing to start the SFTP subsystem, indicating a fundamental misconfiguration in how it’s set up to handle file transfers.

The most common culprit is a malformed or missing Subsystem directive in your sshd_config file. This line tells sshd where to find the SFTP server executable and what arguments to pass it.

1. Incorrect Subsystem Directive Path

Diagnosis: Check your sshd_config file (usually /etc/ssh/sshd_config) for the Subsystem line. It should look something like this:

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

If the path /usr/lib/openssh/sftp-server doesn’t exist on your system, or if it’s misspelled, sshd won’t be able to locate the SFTP server.

Fix:

  1. Find the actual sftp-server executable. On many systems, it’s /usr/lib/openssh/sftp-server. On others, it might be /usr/libexec/openssh/sftp-server or even just /usr/sbin/sftp-server. You can use find / -name sftp-server 2>/dev/null to locate it if you’re unsure.
  2. Edit /etc/ssh/sshd_config and update the Subsystem line to point to the correct path. For example:
    Subsystem sftp /usr/libexec/openssh/sftp-server
    
  3. Restart the SSH service: sudo systemctl restart sshd (or sudo service ssh restart on older systems).

Why it works: This ensures sshd knows precisely where to find the SFTP server program when a client requests an SFTP session.

2. Incorrect Subsystem Directive Name

Diagnosis: The Subsystem directive has two parts: the subsystem name and the command to execute. The name must be sftp.

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

If you’ve accidentally changed sftp to something else, like sftp-server, the client’s request will not match, and sshd will reject it.

Fix:

  1. Edit /etc/ssh/sshd_config.
  2. Ensure the line starts with Subsystem sftp followed by the path to the executable.
    Subsystem sftp /usr/lib/openssh/sftp-server
    
  3. Restart sshd: sudo systemctl restart sshd.

Why it works: The SSH protocol specifies sftp as the keyword for the SFTP subsystem. sshd listens for this specific keyword in the client’s request.

3. Permissions Issues on sftp-server Executable

Diagnosis: Even if the path is correct, sshd needs execute permissions on the sftp-server binary. If these permissions are too restrictive, sshd will fail to launch it.

Fix:

  1. Check the permissions of the sftp-server executable: ls -l /usr/lib/openssh/sftp-server (replace path as needed).
  2. Ensure it has execute permissions for the user sshd runs as (usually root). It should look something like -rwxr-xr-x.
  3. If not, fix them: sudo chmod 755 /usr/lib/openssh/sftp-server.
  4. Restart sshd: sudo systemctl restart sshd.

Why it works: sshd needs to execute the sftp-server program as a child process. Without execute permissions, this operation fails, leading to the subsystem error.

4. SELinux or AppArmor Restrictions

Diagnosis: Security modules like SELinux (on Red Hat-based systems) or AppArmor (on Debian/Ubuntu-based systems) can prevent sshd from executing sftp-server, even if file permissions are correct.

Fix (SELinux):

  1. Check SELinux audit logs for denials: sudo ausearch -m avc -ts recent. Look for entries related to sshd and sftp-server.
  2. If you see a denial, you might need to adjust the SELinux context. A common fix for the sftp-server executable is:
    sudo semanage fcontext -a -t ssh_exec_t "/usr/lib/openssh/sftp-server"
    sudo restorecon -v /usr/lib/openssh/sftp-server
    
    (Adjust the path to sftp-server if necessary).
  3. Restart sshd: sudo systemctl restart sshd.

Fix (AppArmor):

  1. Check AppArmor logs: sudo dmesg | grep "DENIED" or sudo tail /var/log/audit/audit.log (if auditd is running).
  2. If sftp-server is being denied, you may need to update its AppArmor profile (usually located in /etc/apparmor.d/). This is more complex and often involves creating or modifying rules to allow sshd to execute sftp-server with specific arguments. A simpler (but less secure) temporary workaround is to disable AppArmor for sshd:
    sudo aa-complain /usr/sbin/sshd
    
    Then restart sshd. If this works, you’ll need to create a proper profile.
  3. Restart sshd: sudo systemctl restart sshd.

Why it works: These security modules enforce granular access controls. If the policy doesn’t explicitly allow sshd to execute sftp-server from its expected location, the operation is blocked.

5. /bin/bash or /bin/sh Not Accessible/Executable for Users

Diagnosis: If users are being chrooted or restricted to SFTP-only, sshd might be configured to use a specific shell for these users (e.g., /sbin/nologin or /usr/lib/openssh/sftp-server itself). However, if the Subsystem directive is not set to use sftp-server directly and instead relies on the user’s default shell for some reason, or if SFTP is configured in a way that implicitly requires a shell, then issues with shell executability can surface. More commonly, if you’re using internal-sftp in sshd_config for chrooting, the actual shell for the user might still be checked by PAM modules or other SSH configurations.

A more direct cause related to the Subsystem directive itself is when sshd tries to execute the sftp-server binary, and that binary, in turn, tries to launch a shell (e.g., /bin/bash) for its environment, but that shell is not accessible.

Fix:

  1. Ensure that the shell specified in /etc/passwd for the user (or the default shell if not specified) is valid and executable. For SFTP-only users, this is often /sbin/nologin or /usr/sbin/sftp-server.
  2. Verify permissions on /bin/bash (or /bin/sh, or whatever shell is being used): ls -l /bin/bash. It should be executable.
  3. If you are using internal-sftp for chrooting, ensure the chroot directory and its parent directories are owned by root and not writable by other users.
    sudo chown root:root /chroot/sftpuser
    sudo chmod 755 /chroot/sftpuser
    
  4. Restart sshd: sudo systemctl restart sshd.

Why it works: The sftp-server executable might rely on system shells or specific directory structures for its operation. If these underlying components are inaccessible or misconfigured, the SFTP subsystem can fail to initialize.

6. Incorrect sshd_config Syntax (Trailing Spaces, Comments)

Diagnosis: Sometimes, simple typos or hidden characters in sshd_config can cause directives to be ignored or misinterpreted. A common issue is a trailing space after the executable path or an accidental comment character (#) at the beginning of the line.

Fix:

  1. Carefully examine the Subsystem sftp line in /etc/ssh/sshd_config using a text editor that shows hidden characters (like vim with :set list).
  2. Ensure there are no trailing spaces after /usr/lib/openssh/sftp-server.
  3. Make sure the line is not commented out (i.e., it doesn’t start with #).
  4. Remove any extraneous characters.
  5. Save the file and restart sshd: sudo systemctl restart sshd.

Why it works: sshd parses its configuration file line by line. Any syntax error, including invisible ones, can lead to that line being ignored or causing a parsing failure, preventing the Subsystem directive from being processed correctly.

After fixing these, the next error you’ll likely encounter if you’ve missed something is a "Permission denied" error, which would then point to user authentication or file system permissions for the specific user trying to connect.

Want structured learning?

Take the full Ssh course →