Skip to content

/flags/ssh-protocol/ssh-o-pubkeyacceptedalgorithms

ssh -o PubkeyAcceptedAlgorithms=+ssh-rsa: log in with an RSA key to an old SSH server

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
tool
SSH protocol
command
ssh
flag
-o PubkeyAcceptedAlgorithms=+ssh-rsa
default
OpenSSH's built-in list, which since OpenSSH 8.8 contains rsa-sha2-512 and rsa-sha2-256 but not ssh-rsa

ssh -o PubkeyAcceptedAlgorithms=+ssh-rsa -i ~/.ssh/id_rsa user@oldhost lets the client sign the user-authentication request with ssh-rsa (RSA with SHA-1). Since OpenSSH 8.8 the client only uses the SHA-2 variants rsa-sha2-256 and rsa-sha2-512 for RSA keys. Servers that predate RFC 8332 (OpenSSH before 7.2, many embedded devices and old libraries) can only verify ssh-rsa, so the client silently skips the RSA key and the login ends with Permission denied (publickey). Before OpenSSH 8.5 the option was called PubkeyAcceptedKeyTypes.

What the option changes

ssh -G shows the resolved list without connecting:

bash
algs() { ssh -G "$@" 2>/dev/null | awk '$1 == "pubkeyacceptedalgorithms" { print $2 }' | tr ',' '\n'; }
echo "--- default RSA entries:"
algs oldhost.example.org | grep -E '^(rsa-sha2|ssh-rsa)'
echo "--- with +ssh-rsa:"
algs -o PubkeyAcceptedAlgorithms=+ssh-rsa oldhost.example.org | grep -E '^(rsa-sha2|ssh-rsa)'
echo "--- the old name is an alias:"
algs -o PubkeyAcceptedKeyTypes=+ssh-rsa oldhost.example.org | grep -cx ssh-rsa

Output

--- default RSA entries:
rsa-sha2-512-cert-v01@openssh.com
rsa-sha2-256-cert-v01@openssh.com
rsa-sha2-512
rsa-sha2-256
--- with +ssh-rsa:
rsa-sha2-512-cert-v01@openssh.com
rsa-sha2-256-cert-v01@openssh.com
rsa-sha2-512
rsa-sha2-256
ssh-rsa
--- the old name is an alias:
1

The default allows the two SHA-2 signatures for RSA keys; +ssh-rsa appends the SHA-1 one at the end, and the pre-8.5 option name gives the same result.

How to recognise the problem

Run the login with -v. When the client finds no signature algorithm that both sides accept for the RSA key, the debug output contains send_pubkey_test: no mutual signature algorithm, followed by the next authentication method or Permission denied (publickey). When the problem is the host key instead, the connection fails earlier with no matching host key type found, and the fix is HostKeyAlgorithms=+ssh-rsa. Old servers often need both.

SymptomWhich sideOption
no matching host key type found. Their offer: ssh-rsaServer host keyHostKeyAlgorithms +ssh-rsa
Permission denied (publickey) with an RSA key that is authorizedUser key signaturePubkeyAcceptedAlgorithms +ssh-rsa
no matching key exchange method foundKey exchangeKexAlgorithms +...
no matching cipher foundEncryptionCiphers +...

Scope it to the host

~/.ssh/config
Host oldhost
    HostName oldhost.example.org
    User admin
    IdentityFile ~/.ssh/id_rsa
    IdentitiesOnly yes
    PubkeyAcceptedAlgorithms +ssh-rsa
    HostKeyAlgorithms +ssh-rsa

IdentitiesOnly yes stops ssh from offering every key in the agent first, which can trigger Too many authentication failures on servers with a low MaxAuthTries.

Server side

On a new server, PubkeyAcceptedAlgorithms in sshd_config controls which signatures sshd accepts. Adding +ssh-rsa there lets very old clients log in; prefer upgrading those clients or giving them Ed25519 keys. sshd -T | grep pubkeyaccepted prints the effective server list.

Better long-term fix

The key itself is fine; only the SHA-1 signature is weak. Upgrading the server so it understands rsa-sha2-256, or switching the account to an Ed25519 key, removes the need for the option. See Ed25519 vs RSA SSH keys, and get the public key from a private key when you need to install the matching .pub on the server.

FAQ

What is the difference from PubkeyAcceptedKeyTypes?

It is the same option. OpenSSH 8.5 renamed PubkeyAcceptedKeyTypes to PubkeyAcceptedAlgorithms because the list contains signature algorithms rather than key types; the old name still works as an alias.

Why does the server reject my RSA key although it is in authorized_keys?

When the server is too old for rsa-sha2-256 and rsa-sha2-512, the only signature it can verify is ssh-rsa, which modern clients no longer send. Add +ssh-rsa for that host, or the reverse case: a new server whose sshd_config also dropped ssh-rsa rejects old clients.

Does this weaken all my connections?

Only if you set it globally. With the + prefix the safer algorithms stay first, but scoping it to one Host block keeps SHA-1 signatures off for every other server.

Sources