Fix sshd: no hostkeys available -- exiting (WSL, Ubuntu)
Quick fix
sshd: no hostkeys available -- exiting. means sshd found no host key it could load in /etc/ssh. Generate the missing keys and start the server again:
sudo ssh-keygen -A && sudo service ssh start (or sudo systemctl restart ssh when systemd is running).
If the keys already exist, fix their permissions with sudo chmod 600 /etc/ssh/ssh_host_*_key.On this page
sshd: no hostkeys available -- exiting. is printed when the OpenSSH server starts and cannot load a single host key from /etc/ssh. The fix is one command, sudo ssh-keygen -A, which creates every missing host key type. This guide shows the exact output before and after, why WSL and container images ship without keys, the other two causes that print the same line (bad permissions and a wrong HostKey path), and what clients see after the keys change.
The error
On WSL without systemd, starting the server with the SysV init script looks like this:
$ sudo service ssh start
* Starting OpenBSD Secure Shell server sshd
sshd: no hostkeys available -- exiting. [fail]With systemd (a normal Ubuntu server, or WSL with systemd enabled) the unit fails instead, because ssh.service runs sshd -t as ExecStartPre:
$ sudo systemctl restart ssh
Job for ssh.service failed because the control process exited with error code.
$ sudo journalctl -u ssh -n 5 --no-pager
... sshd[812]: sshd: no hostkeys available -- exiting.
... systemd[1]: ssh.service: Control process exited, code=exited, status=1/FAILUREYou can reproduce the check yourself at any time, without starting anything:
sudo /usr/sbin/sshd -tsshd -t validates the configuration and the host keys, then exits. No output and exit code 0 means sshd will start.
Fix: generate the missing host keys
sudo ssh-keygen -AExpected output when keys were missing:
ssh-keygen: generating new host keys: RSA ECDSA ED25519-A creates every default host key type that does not exist yet, with the default paths and an empty passphrase. It never overwrites a key that is already there, so it is safe to run again: on a host that already has all three keys it prints nothing.
Confirm the files exist and sshd accepts them, then start the server:
ls -l /etc/ssh/ssh_host_*
sudo /usr/sbin/sshd -t && echo "config OK"
sudo service ssh start # WSL without systemd
sudo systemctl restart ssh # systemd hosts, including WSL with systemd=trueYou should see six files: ssh_host_rsa_key, ssh_host_ecdsa_key, ssh_host_ed25519_key and their .pub files. The private keys must be mode 600 and owned by root.
On Debian and Ubuntu there is a package-level alternative that does the same thing through the openssh-server maintainer script:
sudo dpkg-reconfigure openssh-serverIt prints Creating SSH2 ED25519 key; this may take some time ... for each missing type and then tries to restart the service.
Why sshd has no host keys
Host keys identify the server, so they must be unique per machine. Anything that is built once and copied many times deliberately ships without them, and something at first boot is supposed to create them. When that first-boot step never runs, sshd has nothing to load.
- WSL distributions. The distro is unpacked from a root filesystem image, and
openssh-serveris often installed later or was installed in the image with its keys removed. Without systemd and cloud-init, nothing generates keys on first start. - Docker and other container images. Base images remove
/etc/ssh/ssh_host_*so two containers never share a key. Installingopenssh-serverin aDockerfileand then deleting or not copying the keys gives the same error atCMD ["/usr/sbin/sshd", "-D"]. - Golden images and clones. VM templates are commonly “sealed” by deleting host keys; cloud-init or a first-boot script normally recreates them. Clones made without that step fail.
- Someone deleted or rotated the keys and did not regenerate them, or restored
/etc/sshfrom a backup without the private keys.
Same error, different cause: permissions or HostKey path
If ls /etc/ssh/ssh_host_* shows the keys but sshd still exits, run sshd -t and read the lines above the error.
Private keys readable by others. sshd refuses any private host key that group or other can read:
$ sudo /usr/sbin/sshd -t
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/etc/ssh/ssh_host_ed25519_key' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
sshd: no hostkeys available -- exiting.Fix the mode and owner:
sudo chown root:root /etc/ssh/ssh_host_*
sudo chmod 600 /etc/ssh/ssh_host_*_key
sudo chmod 644 /etc/ssh/ssh_host_*_key.pubThis happens most often after copying keys from a Windows path (/mnt/c/...) in WSL, because DrvFs files appear with permissive modes unless the mount uses the metadata option.
HostKey points at files that do not exist. If sshd_config or a drop-in under /etc/ssh/sshd_config.d/ sets HostKey, sshd loads only those paths. Print what sshd will actually use:
sudo /usr/sbin/sshd -T | grep -i '^hostkey 'hostkey /etc/ssh/ssh_host_rsa_key
hostkey /etc/ssh/ssh_host_ecdsa_key
hostkey /etc/ssh/ssh_host_ed25519_keyEvery path listed must exist. Either generate a key at that custom path (sudo ssh-keygen -t ed25519 -f /path/to/key -N '') or remove the custom HostKey line.
Fix checklist
- Run
sudo /usr/sbin/sshd -tand read every line it prints. - No keys in
/etc/ssh: runsudo ssh-keygen -A. - Keys present but “UNPROTECTED PRIVATE KEY FILE”:
chmod 600the private keys, ownerroot:root. - Custom
HostKeylines: checksshd -T | grep -i '^hostkey 'and make each path exist. - Run
sshd -tagain until it prints nothing, then start or restart the service. - Connect once from a client and accept the new host key fingerprint (see the FAQ below).
WSL notes
With or without systemd. Check whether WSL booted systemd with
ps -p 1 -o comm=. If it printssystemd, usesystemctl. If not, usesudo service ssh start, which does not survive awsl --shutdown. To get systemd, add this to/etc/wsl.confinside the distro and runwsl --shutdownfrom Windows:ini[boot] systemd=truePrivilege separation directory. Running
/usr/sbin/sshddirectly (not throughserviceor systemd) can fail withMissing privilege separation directory: /run/sshd. Create it withsudo mkdir -p /run/sshd; the init script and the systemd unit normally do this for you.Port 22 already in use. If the Windows OpenSSH Server service is also running, pick a different
Portfor the WSL sshd or stop the Windows service.Reaching WSL from another machine. In the default NAT networking mode, WSL is only reachable from the Windows host. Either set
networkingMode=mirroredunder[wsl2]in%UserProfile%\.wslconfig(Windows 11 22H2 and later), or forward a port withnetsh interface portproxyand allow it in Windows Firewall.
Ubuntu and distro differences
| System | OpenSSH | How keys are normally created | Notes |
|---|---|---|---|
| Ubuntu 24.04 LTS | 9.6p1 | openssh-server postinst at install | ssh.socket is enabled by default; ssh.service runs sshd -t before starting |
| Ubuntu 26.04 LTS | 10.2p1 | openssh-server postinst at install | Same unit layout as 24.04; DSA keys no longer exist in OpenSSH 10 |
| Debian 12 and 13 | 9.2p1, 10.0p1 | postinst, or dpkg-reconfigure openssh-server | Same fix |
| Fedora, RHEL, Rocky | varies | sshd-keygen@.service at boot, per key type | sudo ssh-keygen -A also works |
| Alpine | varies | not created by apk add openssh-server | In containers, run ssh-keygen -A in the entrypoint |
On Ubuntu 24.04 and 26.04 socket activation means ssh.socket can be listening while every connection is reset because ssh.service fails its sshd -t check. Look at journalctl -u ssh, not only at systemctl status ssh.socket. If you also change Port in sshd_config, run sudo systemctl daemon-reload and sudo systemctl restart ssh.socket so the socket picks up the new port.
Containers: generate keys at start, not at build
Running ssh-keygen -A in a Dockerfile bakes one set of host keys into the image, so every container started from it has the same identity. Generate them when the container starts instead:
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y --no-install-recommends openssh-server \
&& rm -f /etc/ssh/ssh_host_* && mkdir -p /run/sshd
CMD ["/bin/sh", "-c", "ssh-keygen -A && exec /usr/sbin/sshd -D -e"]If the container must keep a stable identity across restarts, mount the host keys from a volume or a Kubernetes Secret with mode 0600.
FAQ
Is it safe to run ssh-keygen -A on a server that already works?
Yes. It only creates key types that are missing and leaves existing keys untouched, so clients keep seeing the same fingerprints.
Clients now say “REMOTE HOST IDENTIFICATION HAS CHANGED!” What do I do?
That is expected after new host keys are generated: the client remembers the old key in ~/.ssh/known_hosts. Verify the new fingerprint on the server with ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub, then remove the stale entry on the client with ssh-keygen -R hostname (and ssh-keygen -R '[localhost]:2222' for a non-standard port) and connect again.
Why do my WSL host keys disappear?
They should not. Keys live in the distro’s ext4 virtual disk and survive wsl --shutdown and reboots. If they vanish, the distro was reset, unregistered and reimported, or a script is recreating /etc/ssh. Check ls -l --time-style=full-iso /etc/ssh/ssh_host_* to see when they were written.
Can I copy host keys from my old machine?
You can, when you want the new machine to keep the same identity (for example a rebuilt server with the same name). Copy all six files, then set owner root:root, mode 600 on private keys and 644 on .pub files. Never reuse one set of keys across many different machines.
Do I still need a DSA host key?
No. OpenSSH 9.8 disabled DSA by default and OpenSSH 10.0 removed it, so ssh-keygen -A only creates RSA, ECDSA and Ed25519 keys. If an old client cannot connect after that, see SSH no matching host key type found: their offer ssh-dss.