The 'fatal: unable to negotiate: protocol error' occurs when Git's SSH connection fails because the client and server cannot agree on cryptographic algorithms. This typically happens when connecting to older servers that only support deprecated SSH algorithms like ssh-rsa or diffie-hellman-group1-sha1.
The "fatal: unable to negotiate: protocol error" message in Git indicates that the SSH connection between your local machine and the remote Git server failed during the cryptographic handshake. Before any data is transferred, SSH must negotiate several parameters: the key exchange algorithm, host key algorithm, cipher, and MAC algorithm. When you see this error, the client (your machine running a modern version of OpenSSH) and the server are unable to agree on at least one of these parameters. The most common variants you might see include: - "no matching host key type found. Their offer: ssh-rsa" - "no matching key exchange method found. Their offer: diffie-hellman-group1-sha1" - "no matching cipher found" This happens because OpenSSH 8.8 and later disabled the ssh-rsa signature scheme by default (it uses the weak SHA-1 hash), and OpenSSH 7.0+ disabled the diffie-hellman-group1-sha1 key exchange method due to the Logjam attack vulnerability. When connecting to older servers that haven't been updated, these security improvements cause connection failures.
First, run a verbose SSH connection to see exactly what the server offers:
ssh -vvv [email protected]Look for lines like:
- "Their offer: ssh-rsa" (host key algorithm issue)
- "Their offer: diffie-hellman-group1-sha1" (key exchange issue)
- "Their offer: aes128-cbc" (cipher issue)
This tells you which algorithm override you need to configure.
Create or edit your SSH config file at ~/.ssh/config and add settings for the problematic host:
# For ssh-rsa host key issues
Host your-git-server.com
HostKeyAlgorithms +ssh-rsa
PubkeyAcceptedAlgorithms +ssh-rsa
# For diffie-hellman key exchange issues
Host your-git-server.com
KexAlgorithms +diffie-hellman-group1-sha1
# For cipher issues
Host your-git-server.com
Ciphers +aes128-cbcThe + prefix is important - it appends these algorithms to the default set rather than replacing them, so you still get modern algorithms when the server supports them.
After editing, test the connection:
ssh -T [email protected]If you prefer not to modify your global SSH config, you can configure Git to use specific SSH options:
# Set for a specific repository
git config core.sshCommand "ssh -oHostKeyAlgorithms=+ssh-rsa -oPubkeyAcceptedAlgorithms=+ssh-rsa"
# Or set globally
git config --global core.sshCommand "ssh -oHostKeyAlgorithms=+ssh-rsa -oPubkeyAcceptedAlgorithms=+ssh-rsa"For key exchange issues, use:
git config core.sshCommand "ssh -oKexAlgorithms=+diffie-hellman-group1-sha1"You can combine multiple options:
git config core.sshCommand "ssh -oHostKeyAlgorithms=+ssh-rsa -oPubkeyAcceptedAlgorithms=+ssh-rsa -oKexAlgorithms=+diffie-hellman-group1-sha1"For a single Git command without changing any configuration:
GIT_SSH_COMMAND="ssh -oHostKeyAlgorithms=+ssh-rsa -oPubkeyAcceptedAlgorithms=+ssh-rsa" git clone [email protected]:repo.gitThis is useful for testing or scripting where you don't want permanent configuration changes.
Git for Windows includes its own OpenSSH. You may need to edit the system-wide SSH config:
1. Open C:\Program Files\Git\etc\ssh\ssh_config as Administrator
2. Add the required algorithm settings:
Host your-git-server.com
HostKeyAlgorithms +ssh-rsa
PubkeyAcceptedAlgorithms +ssh-rsaAlternatively, create a user config at C:\Users\<username>\.ssh\config with the same content.
If you have ssh-agent running, restart it after making config changes (check Task Manager for ssh-agent.exe and end the process).
If the server cannot be updated and you're uncomfortable enabling deprecated algorithms, switch to HTTPS:
# Change existing repository remote
git remote set-url origin https://your-git-server.com/username/repo.git
# For new clones
git clone https://your-git-server.com/username/repo.gitFor authentication, you can use:
- Personal access tokens (recommended)
- Git credential manager
- Username/password (if the server allows it)
# Store credentials for HTTPS
git config --global credential.helper storeThe most secure solution is to have the server administrator upgrade the SSH configuration to support modern algorithms:
- rsa-sha2-256 and rsa-sha2-512 for host keys (secure RSA with SHA-2)
- curve25519-sha256 or ecdh-sha2-nistp256 for key exchange
- chacha20-poly1305 or aes256-gcm for ciphers
For server administrators, update the SSH server configuration (/etc/ssh/sshd_config) and regenerate host keys if necessary:
# Generate new host keys with modern algorithms
sudo ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""
sudo ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ""
sudo systemctl restart sshdThis eliminates the need for clients to enable deprecated algorithms.
### Security Implications of Enabling Legacy Algorithms
The algorithms disabled by modern OpenSSH were deprecated for valid security reasons:
- ssh-rsa (SHA-1): The SHA-1 hash function has known collision vulnerabilities. While not yet practically exploitable for SSH host key verification, it's considered cryptographically weak.
- diffie-hellman-group1-sha1: Vulnerable to the Logjam attack, which allows attackers with nation-state level resources to potentially break the key exchange.
- CBC-mode ciphers: Vulnerable to the BEAST attack and padding oracle attacks.
By enabling these algorithms, you're accepting additional security risk. Only enable them when necessary, and scope the configuration as narrowly as possible (specific hosts rather than global settings).
### Understanding the SSH Handshake
The SSH handshake negotiates several cryptographic parameters:
1. Key Exchange (KEX): How the shared secret is established (e.g., diffie-hellman-group14-sha256)
2. Host Key Algorithm: How the server proves its identity (e.g., rsa-sha2-512, ed25519)
3. Cipher: How the data is encrypted (e.g., [email protected])
4. MAC: Message authentication code for integrity (e.g., hmac-sha2-256)
The "unable to negotiate" error occurs when there's no overlap between what the client supports and what the server offers for any of these categories.
### Azure DevOps Specific Configuration
Azure DevOps users often encounter this issue. Add to your ~/.ssh/config:
Host ssh.dev.azure.com
User git
HostKeyAlgorithms +ssh-rsa
PubkeyAcceptedAlgorithms +ssh-rsa### GitLab and GitHub
GitHub and GitLab's hosted services support modern algorithms, so you shouldn't need these workarounds for them. If you encounter issues, it's likely a network proxy or corporate firewall issue rather than algorithm negotiation.
### CI/CD Pipeline Configuration
For CI/CD environments, you can set the SSH command in your pipeline:
# GitHub Actions example
- name: Configure SSH for legacy server
run: |
mkdir -p ~/.ssh
echo "Host legacy-server.example.com" >> ~/.ssh/config
echo " HostKeyAlgorithms +ssh-rsa" >> ~/.ssh/config
echo " PubkeyAcceptedAlgorithms +ssh-rsa" >> ~/.ssh/config### Checking Your OpenSSH Version
ssh -V- OpenSSH 7.0+ disabled diffie-hellman-group1-sha1 by default
- OpenSSH 8.2 deprecated ssh-rsa (announced)
- OpenSSH 8.8 disabled ssh-rsa by default
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server
fatal: unable to access: Proxy auto-configuration failed
How to fix 'Proxy auto-configuration failed' in Git
fatal: unable to access: Authentication failed (proxy requires basic auth)
How to fix 'Authentication failed (proxy requires basic auth)' in Git
fatal: unable to access: no_proxy configuration not working
How to fix 'no_proxy configuration not working' in Git
fatal: unable to read tree object in treeless clone
How to fix 'unable to read tree object in treeless clone' in Git