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:
- Find the actual
sftp-serverexecutable. On many systems, it’s/usr/lib/openssh/sftp-server. On others, it might be/usr/libexec/openssh/sftp-serveror even just/usr/sbin/sftp-server. You can usefind / -name sftp-server 2>/dev/nullto locate it if you’re unsure. - Edit
/etc/ssh/sshd_configand update theSubsystemline to point to the correct path. For example:Subsystem sftp /usr/libexec/openssh/sftp-server - Restart the SSH service:
sudo systemctl restart sshd(orsudo service ssh restarton 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:
- Edit
/etc/ssh/sshd_config. - Ensure the line starts with
Subsystem sftpfollowed by the path to the executable.Subsystem sftp /usr/lib/openssh/sftp-server - 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:
- Check the permissions of the
sftp-serverexecutable:ls -l /usr/lib/openssh/sftp-server(replace path as needed). - Ensure it has execute permissions for the user
sshdruns as (usuallyroot). It should look something like-rwxr-xr-x. - If not, fix them:
sudo chmod 755 /usr/lib/openssh/sftp-server. - 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):
- Check SELinux audit logs for denials:
sudo ausearch -m avc -ts recent. Look for entries related tosshdandsftp-server. - If you see a denial, you might need to adjust the SELinux context. A common fix for the
sftp-serverexecutable is:
(Adjust the path tosudo semanage fcontext -a -t ssh_exec_t "/usr/lib/openssh/sftp-server" sudo restorecon -v /usr/lib/openssh/sftp-serversftp-serverif necessary). - Restart
sshd:sudo systemctl restart sshd.
Fix (AppArmor):
- Check AppArmor logs:
sudo dmesg | grep "DENIED"orsudo tail /var/log/audit/audit.log(ifauditdis running). - If
sftp-serveris 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 allowsshdto executesftp-serverwith specific arguments. A simpler (but less secure) temporary workaround is to disable AppArmor forsshd:
Then restartsudo aa-complain /usr/sbin/sshdsshd. If this works, you’ll need to create a proper profile. - 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:
- Ensure that the shell specified in
/etc/passwdfor the user (or the default shell if not specified) is valid and executable. For SFTP-only users, this is often/sbin/nologinor/usr/sbin/sftp-server. - Verify permissions on
/bin/bash(or/bin/sh, or whatever shell is being used):ls -l /bin/bash. It should be executable. - If you are using
internal-sftpfor 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 - 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:
- Carefully examine the
Subsystem sftpline in/etc/ssh/sshd_configusing a text editor that shows hidden characters (likevimwith:set list). - Ensure there are no trailing spaces after
/usr/lib/openssh/sftp-server. - Make sure the line is not commented out (i.e., it doesn’t start with
#). - Remove any extraneous characters.
- 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.