Git SSH "kex_exchange_identification: Connection closed" in CI
By Kaveh Alemi·Latchkey
The remote closed the SSH connection before key exchange even began. This is a transport-level cutoff - a blocked or proxied port 22, a transient rate limit, or a network interruption - not a key or permissions problem.
What this error means
An SSH clone/fetch fails with kex_exchange_identification: Connection closed by remote host and fatal: Could not read from remote repository. It can be intermittent (succeeds on retry) or consistent when port 22 is blocked.
git clone output
kex_exchange_identification: Connection closed by remote host
Connection closed by 140.82.x.x port 22
fatal: Could not read from remote repository.
Common causes
Port 22 blocked or proxied
A firewall or network that does not allow outbound SSH on port 22 closes the connection before the handshake completes.
Transient rate limit or network blip
The host may briefly drop connections under load or rate limiting, so the same command succeeds on a retry.
How to fix it
Use SSH over the HTTPS port (443)
GitHub serves SSH on port 443 via ssh.github.com, which bypasses a blocked port 22.
When the cutoff is intermittent, a bounded retry around the clone clears most blips.
Terminal
for i in 1 2 3; do
git clone git@github.com:org/repo.git && break
echo "ssh clone failed (attempt $i), retrying..."; sleep 5
done
How to prevent it
Allow outbound SSH (port 22), or use ssh.github.com:443 on locked-down networks.
Wrap SSH clones in a bounded retry to absorb transient cutoffs.
Fall back to the HTTPS remote where SSH egress is not permitted.
Frequently asked questions
What causes ""kex_exchange_identification""?
A firewall or network that does not allow outbound SSH on port 22 closes the connection before the handshake completes.
How do I fix "kex_exchange_identification"?
GitHub serves SSH on port 443 via ssh.github.com, which bypasses a blocked port 22.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.