PuTTY displays Network error: Connection timed out? When opening the session, it means no useful response has returned within the expected timeframe. The address or port may be incorrect, the network path may be inaccessible or asymmetric, or a device may be leaving packets unanswered. At this stage, the password and SSH key are not yet at fault.
A connection refused is different: the TCP connection has been rejected, for example by a port without a service listening or by an intermediate device. This refusal does not prove, on its own, that the correct server responded. For this other branch, refer to the Connection refused diagnosis in PuTTY. The manual officially describes the PuTTY timeout as the absence of response from the server and specifically mentions an isolated or powered-off server and an address to verify. It also indicates that a timeout can occur after a loss of contact during a connection: this guide focuses on session opening.
Proceed without blindly modifying the server: first check the destination and the path from Windows, then compare these findings to the listening, the return route, and filtering on the Linux side. For server commands, use an independent console provided by the host, the VM, or physical access. Keep any already open SSH session.
Identify the timeout before changing anything
Note the exact text displayed by PuTTY, the time with the timezone, the session used, the hostname, the port, and the step where the failure occurs. Also note if you are going through a proxy configured in PuTTY, a VPN, or a bastion. The details available in the PuTTY Event Log can help confirm the attempted path and address.
- Timeout on opening: no useful response was received within the timeframe. This points to the address, routing, or silent filtering, without distinguishing between these causes.
- Connection refused: the path received a TCP rejection. Check the dedicated branch for connection refusal.
- Server refused our key: the transport has reached the authentication stage; this is another failure. You can then consult the guide on using an SSH key with PuTTY.
- An established session disconnects after a period of inactivity: this is not the same case as a timeout on opening. Do not rely on a keepalive setting to repair an initial TCP path that is unresponsive.
Do not look for a universal duration to set in PuTTY: extending the wait does not fix either an absent route or a filtered packet.
Check the address, DNS, and actually published port
Open the saved session in PuTTY and check the host and port in the SSH settings. The host field contains a name or address, not a URL with https://. Confirm these values with the administrator or in the provider’s console before replacing them. To review the fields of a session, follow the SSH session settings in PuTTY.
In PowerShell, replace serveur.example.net with the validated name and 22 with the actual published external TCP port for your access. These values are examples, not your server’s parameters.
Resolve-DnsName serveur.example.net -Type A
Resolve-DnsName serveur.example.net -Type AAAA
Test-NetConnection -ComputerName serveur.example.net -Port 22 -InformationLevel Detailed
The first two commands separately display the obtained IPv4 (A) and IPv6 (AAAA) addresses via DNS resolution. Compare the returned address with the expected one in the provider’s console. An AAAA record can lead PuTTY to take a different IPv6 path than the IPv4 path. The Microsoft documentation for Test-NetConnection details the TCP result and route diagnosis.
In the detailed result of Test-NetConnection, note particularly RemoteAddress, SourceAddress, InterfaceAlias, and TcpTestSucceeded. You can separately test an already validated address to distinguish a resolution problem from a TCP failure. Do not use a randomly found address and do not accept a new host key fingerprint without verifying it through a trusted channel.
TcpTestSucceeded : Truemeans that this test has established TCP to that destination, this port, and this path, at that moment. This does not verify the SSH identity of the server. If PuTTY still fails, compare the address and port used, any potential proxy, and the session settings.TcpTestSucceeded : Falseindicates a failure of the TCP test, but does not distinguish on its own a timeout from a refusal nor locate the loss. Keep the exact PuTTY message and continue the checks.
A private address is generally reachable only from the intended network or a VPN with the correct route. In the case of NAT, the port used by the client may differ from the internal listening port: for example, a conceptual external port 2222 may be redirected to the internal port 22. Have the mapping confirmed; do not replace these examples with assumed values. Do not flush the DNS cache reflexively: only do so if an outdated local entry has been demonstrated.
Compare the Windows, VPN, and network paths
Check the active network, access to the expected VPN or bastion, routes, and the source address used. If PuTTY goes through a proxy, a direct PowerShell test does not validate this proxy: the two attempts may not take the same path.
The following commands are readings on the Windows side. For tracert, replace 192.0.2.20 with the address of a server you are authorized to test. 192.0.2.20 is a reserved address for documentation examples, not the actual address of your server.
ipconfig
route print
Test-NetConnection -ComputerName serveur.example.net -DiagnoseRouting -InformationLevel Detailed
tracert -d 192.0.2.20
ipconfig and route print help identify local interfaces and routes. -DiagnoseRouting requests a route diagnosis; this is a distinct set of parameters from the test with -Port, do not combine the two in the same command. tracert shows traversal steps, but asterisks may simply indicate that ICMP responses are not being returned. They do not definitively indicate the device that is blocking SSH. Likewise, a successful ping does not prove that SSH is accessible, and a failed ping does not prove that the server is powered off.
If allowed, compare the same host and port from another network, with other parameters unchanged. A successful connection via a hotspot, for example, points to a difference in path, source, or permission on the first network; it does not automatically prove that the ISP is blocking port 22. A list of allowed source addresses may explain this difference. Check outbound Windows rules and network policies with the administrator. Do not disable any firewall or antivirus and do not bypass a network policy.
Check listening and the return route from Linux
Run these readings from the server’s independent console, not from the failing PuTTY window. Replace 192.0.2.10 with the actual source address that the server sees, after NAT or VPN. 192.0.2.10 is a documentation address to be replaced, not a real client IP. For an IPv6 destination, use ip -6 route get with the observed IPv6 address.
ip -br address
ip route
ip route get 192.0.2.10
sudo ss -ltnp
systemctl list-unit-files 'ssh*' --no-pager
sudo /usr/sbin/sshd -t
sudo /usr/sbin/sshd -T
ip -br address summarizes the addresses of the interfaces; ip route displays the IPv4 routes and ip route get indicates the chosen path to the source to be joined in return. Compare this path to the actual route: the presence of a default route does not prove that the response reaches the client. On a distribution where the binary is not in /usr/sbin/sshd, adapt its known path rather than concluding on its absence.
ss -ltnp shows the TCP sockets in listening state and, depending on the rights, the associated process. Check the internal port and the listening address: listening limited to 127.0.0.1 is not accessible from the outside. A listening on [::] does not guarantee IPv4 accessibility on its own. The public address of a server behind NAT may not necessarily appear on its Linux interfaces.
Identify the unit actually used before checking its status. Depending on the distribution, it may be called ssh.service or sshd.service; socket activation may use ssh.socket. An unknown unit does not necessarily mean that SSH is absent. Only check the identified unit, for example:
systemctl status ssh.service --no-pager
Replace ssh.service with the existing unit. The manual for OpenSSH’s sshd describes -t as a configuration and key consistency check, and -T as displaying the effective configuration. These options do not restart the service. Match directives may depend on the connection parameters; -T alone does not therefore prove the configuration applicable to each client. With socket activation, also observe the real listening with ss and the socket unit.
The ListenAddress and Port directives determine listening addresses and ports in the configuration; they do not guarantee routing, firewall rules, or NAT port publication. A port without listening often produces a refusal if the packet reaches the host without silent filtering: do not conclude that every timeout means the SSH service is stopped.
Locate filtering without exposing SSH to the entire Internet
Identify the firewall in use before interpreting its rules. These commands are readings and may not all be available on your distribution:
sudo ufw status verbose
sudo nft list ruleset
sudo firewall-cmd --get-active-zones
If firewalld is active, then check the zone actually associated with the interface, replacing ZONE with its name:
sudo firewall-cmd --zone=ZONE --list-all
An absent command does not demonstrate that no filtering exists: a rule may be in another manager, on a router, or with the host. Do not combine firewall managers to try to fix the failure.
For the rule corresponding to the observed path, check the TCP protocol, internal port, source address seen by the server, order of rules, and action. A DROP rule may leave the connection unanswered; a REJECT may cause a refusal depending on the form of the rejection. Also check security groups or cloud firewalls, provider routes, routers, NAT redirection, VPN, and potential CGNAT. A test of the public address from the LAN depends notably on NAT loopback support; a redirection does not necessarily work behind a CGNAT.
Only correct one rule or route identified by the observations, limiting the source to the necessary addresses. Do not open the port to 0.0.0.0/0 by default and do not move SSH to port 443 as an automatic workaround.
Cross-check logs and a short TCP capture
Check the logs around the noted time, adapting the unit to the one actually used:
sudo journalctl -u ssh.service --since '10 minutes ago' --no-pager
Replace ssh.service with the existing unit, such as sshd.service or, as appropriate, ssh.socket. Some distributions also log events in /var/log/auth.log or /var/log/secure. A timeout that occurred before the SSH exchange may not leave any authentication lines: an empty log does not prove the absence of an attempt.
If tcpdump and GNU timeout are available and you are allowed to capture, replace the port and address with the internal port and source actually seen by the server. Start the capture just before a new PuTTY attempt:
sudo timeout 10 tcpdump -ni any -c 20 'tcp port 22 and host 192.0.2.10'
In this command, port 22 and 192.0.2.10 are documentary examples to be replaced by the observed values, not data from your failure. The capture stops after ten seconds or after twenty packets. Do not use the -A or -X options and do not leave a permanent capture running. Mask the addresses before sharing an output.
- No SYN at the observed point: after checking the interface, capture filter, time, and source address, examine the destination, the return route, or upstream filtering. This does not prove alone that a cloud firewall is blocking traffic.
- SYN received, no response observed: check local filtering, listening, and capture conditions. Do not blame
sshdwithout further evidence. - SYN received then SYN-ACK sent, but no final ACK visible: examine the return path or client/intermediate filtering. A capture on the server side alone does not definitively locate the loss.
- SYN followed by an RST: you are in the TCP rejection branch; refer to the dedicated diagnosis for Connection refused.
- Complete TCP handshake: TCP worked at that moment. Compare the capture to the PuTTY attempt, to the proxy, and to the SSH step reached. This proves neither the identity of the server nor a successful authentication.
Correct a proven cause and validate without cutting SSH
Before any changes, back up the affected file and ensure you have a backup console. Proceed with one modification at a time: correct the session destination, the VPN route, or the specific rule that the tests highlighted. If you do not have an independent console, stop remote changes and send the results to the administrator.
Do not modify keys, passwords, PermitRootLogin, or SSH algorithms to fix a network silence before authentication. If you change the SSH configuration, first ensure sshd -t succeeds, then use the reload supported by the unit and distribution after verifying their functionality. A restart or a reboot is not a first test, and a reload does not necessarily fix a poorly exposed systemd socket.
Never run ufw disable, nft flush ruleset, or iptables -F. Do not stop Fail2ban blindly, do not open SSH to all sources, and do not close the old session before validation.
After a correction, keep the console and old session open. In a new PuTTY window, retest the same host, the same port, and the same path. Verify the SSH fingerprint through a trusted channel, proceed to authentication, and confirm that a session is working. If the message becomes Connection refused, return to that branch rather than continuing the timeout diagnosis.
To request help, provide the time, host, and port, the resolved addresses and source address, the VPN/proxy path, the TCP results, and the server-side observations, along with the suspect rule. Exclude sensitive addresses and information. Do not present an output of a command not executed as a result.