The 'Connection closed by UNKNOWN port 65535' error occurs when an SSH connection is terminated before completing the key exchange and authentication process. This typically indicates a proxy/firewall issue, incompatible key exchange algorithms, authentication failures, or network connectivity problems between your client and the SSH server.
The "Connection closed by UNKNOWN port 65535" error message indicates that the SSH server has closed the TCP connection before the SSH protocol handshake could complete. The error appears during the key exchange phase (kex_exchange_identification), which happens before authentication. Key aspects of this error: - **UNKNOWN port 65535**: The error message shows "UNKNOWN" because the connection was terminated before SSH could identify the remote endpoint properly. Port 65535 is the maximum possible port number and usually appears as a placeholder when the actual port cannot be determined. - **Early termination**: Unlike "Connection refused" (immediate rejection), this means the connection was initially accepted but then closed by an intermediary or the server before SSH could handshake. - **Likely culprit**: The problem is usually not SSH itself, but something between you and the SSH server (firewall, proxy, tunnel, or network device). This error commonly occurs when: 1. Using SSH through HTTP proxies or tunneling solutions 2. Connecting through corporate firewalls or network appliances 3. Using Cloudflare Tunnel, AWS Session Manager, or similar services 4. Network routing issues or interrupted connections 5. SSH daemon crashing or misconfigured to close connections early
Run SSH with maximum verbosity to see exactly where the connection fails:
ssh -vvv user@hostnameOutput to a file for easier analysis:
ssh -vvv user@hostname > ssh-debug.log 2>&1
cat ssh-debug.logLook for the line showing "kex_exchange_identification" - this is where it fails. Check what happens immediately after and before the error. This will tell you if the connection is being accepted initially or rejected immediately.
If you have access to the server, check if the SSH daemon is running:
# On the remote server
sudo systemctl status ssh
# or
sudo systemctl status sshd
# or on some systems
sudo service ssh status
# If stopped, start it
sudo systemctl start ssh
sudo systemctl enable ssh # Enable on bootIf SSH daemon keeps crashing, check the logs:
sudo tail -50 /var/log/auth.log
# or on systemd
sudo journalctl -u ssh -n 50Look for errors like "fatal error" or "error in libcrypto".
The SSH daemon must listen on the correct network interface. Check /etc/ssh/sshd_config:
sudo grep ListenAddress /etc/ssh/sshd_configDefault is often commented out (meaning listen on all interfaces):
# Listen on all IPv4 addresses
#ListenAddress 0.0.0.0
# Listen on all IPv6 addresses
#ListenAddress ::If you see specific addresses like:
ListenAddress 127.0.0.1This means SSH only listens on localhost. To fix, either:
1. Comment it out (listen on all interfaces)
2. Add your network interface:
sudo nano /etc/ssh/sshd_config
# Comment out restrictive ListenAddress
#ListenAddress 127.0.0.1
# Or add multiple addresses
ListenAddress 0.0.0.0
ListenAddress ::Then restart:
sudo systemctl restart sshTest if the issue is specific to the host/port combination:
# Try localhost if you have server access
ssh -p 22 localhost
# Try a different interface/IP if the server is multi-homed
ssh [email protected]
# Try IPv6 if IPv4 fails
ssh user@[::1]
# Try a different SSH port if server listens on non-standard port
ssh -p 2222 user@hostnameIf one works but others don't, the problem is network routing or firewall rules, not the SSH daemon itself.
Verify that firewall rules allow SSH traffic:
# Check UFW (Ubuntu)
sudo ufw status
sudo ufw allow 22/tcp
sudo ufw enable
# Check iptables
sudo iptables -L -n | grep ssh
# or
sudo iptables -L -n | grep 22
# Add SSH rule if missing
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables-save # Persist changes (varies by distro)
# Check if SSH port is even open
netstat -tuln | grep 22
# or
ss -tuln | grep 22If the port isn't shown as LISTEN, SSH daemon isn't running or not listening on that interface.
For cloud providers:
# AWS Security Group - Allow SSH on port 22
# Azure Network Security Group - Allow port 22 inbound
# GCP Firewall - Allow ingress on port 22Older SSH clients and servers may have incompatible algorithms. Add compatible algorithms to your SSH config:
nano ~/.ssh/configAdd or update the host section:
Host hostname
User username
KexAlgorithms curve25519-sha256,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group16-sha512,diffie-hellman-group14-sha256
HostKeyAlgorithms ecdsa-sha2-nistp256,rsa-sha2-256,ssh-rsa
Ciphers aes256-ctr,aes192-ctr,aes128-ctrOr enable via command line:
ssh -oKexAlgorithms=curve25519-sha256 user@hostnameOn the server side, update /etc/ssh/sshd_config:
sudo nano /etc/ssh/sshd_config
# Add supported algorithms
KexAlgorithms curve25519-sha256,ecdh-sha2-nistp521,diffie-hellman-group16-sha512
HostKeyAlgorithms ecdsa-sha2-nistp256,rsa-sha2-256Then restart:
sudo systemctl restart sshIf you're connecting through a proxy, tunnel, or bastion host, that's likely the culprit:
# SSH through a bastion/jump host
ssh -J bastion@jump-host user@target-host
# SSH through ProxyCommand
ssh -oProxyCommand="nc -X connect -x proxy:3128 %h %p" user@hostname
# SSH through SSH tunnel (local port forward)
ssh -L 2222:target-host:22 user@bastion-host
# Then in another terminal:
ssh -p 2222 user@localhostIf using Cloudflare Tunnel or AWS Session Manager:
# Install Session Manager plugin for AWS
aws ssm start-session --target instance-id --document-name AWS-StartSSHSession --parameters 'portNumber=%port%'
# Or use Cloudflare Tunnel
cloudflared tunnel --url ssh://localhost:22The issue is often that the proxy/tunnel doesn't properly forward raw SSH protocol. Some options:
1. Use SSH over HTTPS if available:
ssh -o ProxyCommand="openssl s_client -quiet -proxy proxy:3128 -servername %h -connect %h:%p" user@hostname2. Use GitHub's SSH over HTTPS endpoint (if relevant):
ssh -p 443 [email protected]3. Contact your network admin to whitelist SSH traffic through the proxy
If the SSH daemon crashed or is in a bad state, restart it:
# On the remote server (requires local access or out-of-band access)
sudo systemctl restart ssh
# Or if using init.d
sudo service ssh restart
# Or force restart
sudo systemctl kill -9 ssh
sudo systemctl start sshIf you can't access the server, you may need to:
- Use console access (cloud provider console)
- Use out-of-band management (IPMI, OLO, etc.)
- Reboot the server if it's hung:
sudo rebootSSH servers have MaxAuthTries limit. Too many failed attempts cause disconnection:
# Check the limit
sudo grep MaxAuthTries /etc/ssh/sshd_config
# Default is usually 6
# Increase if needed (on the server)
sudo nano /etc/ssh/sshd_config
# Change:
MaxAuthTries 10 # Increased from default 6
# Or disable the limit (less secure)
MaxAuthTries 0 # UnlimitedThen restart SSH:
sudo systemctl restart sshOn the client side, check how many keys you're offering:
# List all keys SSH will try
ssh-add -l
# To limit which keys are used
ssh -o IdentitiesOnly=yes -i /path/to/key user@hostnameHostname resolution issues might be the cause. Try connecting directly to the IP:
# If hostname doesn't work
ssh [email protected]
# Try the IP address instead
ssh [email protected]
# Or use -o StrictHostKeyChecking=no to skip host key check
ssh -o StrictHostKeyChecking=no user@hostnameIf IP works but hostname doesn't, the problem is DNS or hostname routing.
To diagnose:
# Check DNS resolution
nslookup example.com
dig example.com
# Check routing to the host
traceroute example.com
mtr example.com # Better real-time monitoringIf the IP is routed through a firewall or proxy that doesn't handle SSH well, it might explain the error.
Understanding the "UNKNOWN port 65535" message:
Port 65535 is the maximum valid port number in TCP (2^16 - 1). When SSH reports "UNKNOWN port 65535", it's because the connection was closed before SSH could identify the remote port. This is a placeholder value indicating the port information was lost. It typically means an intermediary (firewall, proxy, load balancer) closed the connection.
SSH protocol handshake phases:
The SSH protocol has several phases, and "kex_exchange_identification" is the very first:
1. Banner exchange - Send protocol version
2. Key exchange (kex) - Agree on encryption algorithms
3. Authentication - Send credentials (keys or password)
4. Channel open - Start SSH session
If the connection closes during phase 1-2, the error is almost always not on the SSH application itself, but on the network/firewall side.
Proxy and tunneling issues:
When SSH traffic goes through HTTP proxies or tunneling solutions:
- Some proxies don't allow CONNECT tunneling (needed for SSH)
- Some proxies only allow HTTPS (port 443)
- Some proxies buffer data incorrectly, causing SSH to think the connection is broken
- Some proxies have timeouts too short for SSH negotiation
Solutions vary by proxy:
- SOCKS5 proxies usually work better than HTTP proxies
- SSH over HTTPS (port 443) is more likely to work through corporate proxies
- Direct tunneling via ProxyCommand is more reliable than ProxyUseFdpass
SSH algorithm compatibility:
Modern OpenSSH (7.4+) has disabled older algorithms (ssh-dss, ssh-rsa, diffie-hellman-group1-sha1) for security. If your server is very old or your client is new, algorithm mismatch causes connection closure. Adding explicit algorithms in ssh_config or sshd_config resolves this.
Key exchange failure debugging:
When debugging kex failures:
# See supported algorithms on your SSH version
ssh -Q kex # Key exchange algorithms
ssh -Q cipher # Ciphers
ssh -Q mac # Message authentication codes
ssh -Q key # Host key typesCompare with server using:
# Connect to server and see what it offers (before auth)
# Check /etc/ssh/sshd_config for allowed algorithms
sudo sshd -T | grep -E "^kex|cipher|mac|hostkey"Common causes by environment:
- AWS/GCP/Azure: Usually network security groups/NACLs, or the instance's SSH daemon not running
- GitHub/GitLab/Gitea: Proxy issues or using wrong port (443 vs 22)
- Corporate networks: Firewall proxy not allowing SSH or intercepting it
- Docker containers: SSH daemon not running inside container, or port mapping issues
- CI/CD pipelines: Agent can't reach git server due to network segmentation
Testing without credentials:
To isolate authentication issues from connection issues:
# Just try to connect (will fail at auth, but shows if kex works)
ssh -o PubkeyAuthentication=no user@hostnameIf this still shows "Connection closed by UNKNOWN", it's definitely a network/handshake issue, not authentication.
Load key "/home/user/.ssh/id_rsa": invalid format
How to fix 'Load key invalid format' in SSH
Bad owner or permissions on /home/user/.ssh/config
How to fix "Bad owner or permissions on .ssh/config" in SSH
Error connecting to agent: Connection refused
How to fix "Error connecting to agent: Connection refused" in SSH
Offending ECDSA key in /home/user/.ssh/known_hosts:line
How to fix "Offending ECDSA key in known_hosts" in SSH
bind: Address already in use
How to fix "bind: Address already in use" in SSH