Introduction
During the SSH handshake, the client and server negotiate which encryption cipher, key exchange algorithm, and MAC (message authentication code) to use. If there is no common algorithm between the two sides, the connection fails with no matching cipher found, no matching key exchange method found, or no matching MAC found. This commonly occurs when connecting from a modern client to a legacy server, or when security hardening disables older algorithms on one side.
Symptoms
ssh user@old-serverfails withno matching cipher found. Their offer: aes128-cbc,3des-cbcUnable to negotiate with X port 22: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1no matching MAC found. Their offer: hmac-sha1,hmac-md5- Connection fails immediately after TCP connection is established
ssh -vshows the algorithm lists from both sides with no overlap
Common Causes
- Modern SSH client (OpenSSH 8.8+) disables weak algorithms by default
- Legacy SSH server only supports deprecated algorithms (3des-cbc, diffie-hellman-group1-sha1)
- Security hardening (CIS benchmarks) removed all but the strongest algorithms
- Network equipment (Cisco IOS, old routers) using obsolete SSH implementations
- FIPS mode enabled on one side restricting available algorithms
Step-by-Step Fix
- 1.Identify the incompatible algorithms with verbose output:
- 2.```bash
- 3.ssh -v user@old-server 2>&1 | grep -E "offer|match|no matching"
- 4.# Shows exactly which algorithms each side supports
- 5.
` - 6.Check available algorithms on both sides:
- 7.```bash
- 8.# On the client:
- 9.ssh -Q cipher
- 10.ssh -Q kex
- 11.ssh -Q mac
# On the server: sshd -T | grep -E "ciphers|kexalgorithms|macs" ```
- 1.Connect by enabling the required legacy algorithms:
- 2.```bash
- 3.# Enable specific weak algorithms for this connection only
- 4.ssh -o KexAlgorithms=+diffie-hellman-group1-sha1 \
- 5.-o Ciphers=+aes128-cbc \
- 6.-o HostKeyAlgorithms=+ssh-rsa \
- 7.user@old-server
- 8.
` - 9.Make the configuration persistent for specific hosts:
- 10.```bash
- 11.# In ~/.ssh/config:
- 12.Host legacy-server
- 13.HostName 10.0.5.100
- 14.User admin
- 15.KexAlgorithms +diffie-hellman-group1-sha1
- 16.Ciphers +aes128-cbc,3des-cbc
- 17.HostKeyAlgorithms +ssh-rsa
- 18.MACs +hmac-sha1,hmac-md5
- 19.
` - 20.Upgrade the server's SSH configuration (preferred long-term fix):
- 21.```bash
- 22.# On the legacy server, update sshd_config:
- 23.Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes128-gcm@openssh.com
- 24.KexAlgorithms curve25519-sha256,diffie-hellman-group-exchange-sha256
- 25.MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
- 26.sudo systemctl restart sshd
- 27.
` - 28.For network equipment that cannot be upgraded, use a jump host:
- 29.```bash
- 30.# SSH to a modern jump host first, then use its SSH client to reach the legacy device
- 31.ssh -J modern-jump user@legacy-switch
- 32.# The jump host may have a more permissive SSH config
- 33.
`
Prevention
- Plan algorithm compatibility when deploying new SSH servers or upgrading clients
- Maintain a list of legacy systems requiring special SSH configuration
- Use SSH certificates to reduce dependency on specific key exchange algorithms
- Document special SSH config requirements for each legacy system
- Create SSH config snippets that can be included for specific device types (network-equipment, legacy-linux, etc.)