A Windows SSH server can show as Running and still be unreachable. The service status confirms that the process started; it doesn’t confirm that the server is listening on the expected port, that a firewall allows connections, or that login will succeed.
The fastest way to diagnose the problem is to check those layers in order.
1. Check whether the server service exists and is running
Open PowerShell and run:
Get-Service sshd
If the service is running, you’ll see Status as Running. If it says Stopped, OpenSSH Server is installed but isn’t currently active. If PowerShell says it can’t find a service named sshd, check whether the server capability is installed:
Get-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
A state of NotPresent means it isn’t installed. You can install the capability with:
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
For the full setup—including enabling the service and configuring access—see this guide to setting up an SSH server on Windows.
One easy mix-up: sshd is the server that accepts incoming SSH connections. ssh-agent is a separate client-side service that can hold decrypted keys. Whether ssh-agent is running does not tell you whether the server is accepting connections.
2. Confirm that sshd owns the listening port
A running service still needs to listen on a TCP port. The default is 22, so check it with:
Get-NetTCPConnection -LocalPort 22 -State Listen
A result means something is listening on port 22, but it doesn’t identify the process. Check the owning process ID:
Get-Process -Id (Get-NetTCPConnection -LocalPort 22 -State Listen).OwningProcess
The process name should be sshd. If another process owns the port, that process—not OpenSSH—is listening there. If the first command returns nothing, sshd may have failed to bind or may be configured to use a different port.
For older Windows builds, netstat is another option:
netstat -ano | findstr ":22"
Look for LISTENING. The last column is the process ID, which you can check with Get-Process -Id <PID>.
If you configured a custom port, such as 2222, use that port in your checks instead. The Port directive is in:
C:\ProgramData\ssh\sshd_config
For example:
Get-NetTCPConnection -LocalPort 2222 -State Listen
3. Check the Windows firewall rule
A service can listen locally while the firewall blocks incoming connections. OpenSSH Server installation creates an inbound rule for TCP port 22. Inspect it with:
Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" |
Select-Object Name, Enabled, Direction, Action
The rule should be enabled, inbound, and allow traffic. If it’s missing, you can create it with:
New-NetFirewallRule -Name "OpenSSH-Server-In-TCP" `
-DisplayName "OpenSSH Server (sshd)" `
-Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
If sshd listens on a custom port, the firewall rule must allow that port too. The default rule only covers port 22. Also check any third-party firewall or endpoint security software; it may have its own rules.
4. Test locally, then from another device
From the Windows machine running the server, test the local TCP connection:
Test-NetConnection -ComputerName localhost -Port 22
Look for TcpTestSucceeded: True. This checks the local TCP path, not authentication or remote reachability. If you use port 2222, test port 2222 instead.
Next, run the test from another machine on the same network, using the Windows server’s hostname or IP address:
Test-NetConnection -ComputerName 192.168.1.50 -Port 22
This is a useful way to distinguish a local service problem from a firewall or network-path problem. The PowerShell Test-NetConnection reference explains how to read its results and use it to test TCP ports.
If the local test succeeds but the remote one fails, check the Windows firewall, network routing, and any cloud-provider firewall or security group. A successful test from another device on your LAN does not prove the server is reachable from the public internet. That may require router port forwarding or another intentional remote-access setup.
5. Try an actual SSH login
A port test only confirms TCP reachability. It doesn’t check whether a user can authenticate. From the client machine, try:
ssh username@hostname
For a custom port:
ssh -p 2222 username@hostname
If you reach a password or key prompt but authentication fails, the network path is working far enough to reach SSH. Check the username, password or key, and the server’s authentication settings. Restarting the service or opening more firewall ports won’t fix an incorrect login or a key that isn’t installed correctly.
A quick way to read the symptoms
-
No
sshdservice: OpenSSH Server may not be installed. - Service stopped: The server process isn’t active.
- Service running, no listener: Check the configured port and server startup.
- Listener present, remote TCP test fails: Check firewall rules and the network path.
- TCP test succeeds, login fails: Investigate authentication rather than reachability.
Treat “SSH is running” as the start of the diagnosis, not the end. Checking the service, listener, firewall, network path, and login separately makes it much easier to find the layer that’s actually failing.
I originally published a more detailed version of this guide on the SSHFlow blog.
I'm also building SSHFlow — an SSH client where every server gets its own workspace for terminals, SFTP, code, and databases.
Top comments (0)