Git & CI/CD Intermediate

Troubleshooting ‘Git SSH connection closed by foreign host port 22 fatal protocol’ on Ubuntu 22.04 LTS

Resolve 'Git SSH connection closed by foreign host' on Ubuntu 22.04 LTS. This guide covers SSH key issues, server configurations, firewall blocks, and client-side problems causing Git protocol errors.

👨‍💻
Senior Systems Architect • Verified in Staging Labs

Resolve 'Git SSH connection closed by foreign host' on Ubuntu 22.04 LTS. This guide covers SSH key issues, server configurations, firewall blocks, and client-side problems causing Git protocol errors.

When performing Git operations over SSH, encountering an error like "Git SSH connection closed by foreign host port 22 fatal protocol" can halt your development workflow. This specific error signifies that the underlying SSH connection to the remote Git server (e.g., GitHub, GitLab, your own Git server) failed prematurely, causing Git to receive an unexpected or incomplete response, which it then interprets as a "protocol error." While the message points to a "fatal protocol error" from Git's perspective, the root cause almost always lies within the SSH connection itself rather than Git. This guide will walk you through diagnosing and resolving this issue on your Ubuntu 22.04 LTS client or a remote Ubuntu 22.04 LTS server.

Symptom & Error Signature

The most common manifestation of this issue occurs when attempting to clone, pull, or push code using Git over SSH. You'll typically see output similar to this:

# When trying to clone a repository
git clone [email protected]:youruser/yourrepo.git
Cloning into 'yourrepo'...
ssh_exchange_identification: Connection closed by foreign host
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

# Alternatively, the output might be more direct, leading to the "fatal protocol" message:
git pull origin main
ssh_exchange_identification: Connection closed by foreign host
fatal: protocol error: bad line length character: Git S

The key indicators are ssh_exchange_identification: Connection closed by foreign host followed by a fatal Git error, often related to protocol or repository access. The "port 22" explicitly refers to the standard SSH port.

Root Cause Analysis

The "connection closed by foreign host" message indicates that the remote server (the "foreign host") terminated the SSH connection unexpectedly during the initial handshake phase. This can happen for a multitude of reasons, usually related to security, resource limits, or misconfigurations. Common root causes include:

  1. Firewall Restrictions:
    • Client-side: A local firewall on your Ubuntu 22.04 client machine might be blocking outgoing connections on port 22.
    • Server-side: A firewall (e.g., UFW, iptables, cloud security groups) on the remote Git server is blocking inbound connections on port 22, or specifically from your client's IP address.
  2. SSH Server Configuration Issues (sshd_config):
    • MaxStartups Limit Exceeded: The remote sshd daemon might be configured with a low MaxStartups value, limiting the number of unauthenticated concurrent connection attempts. If the server is under heavy load or experiencing a brute-force attack, new connections, including yours, might be dropped.
    • AllowUsers/DenyUsers Rules: Your username or IP address might be explicitly denied access in the remote server's sshd_config.
    • Protocol Mismatch/Deprecation: Though less common on modern systems, an outdated or misconfigured Protocol setting on the server could cause issues during the handshake.
  3. SSH Key Authentication Problems:
    • Incorrect Public Key: The public key registered on the remote server (e.g., in ~/.ssh/authorized_keys or the Git hosting platform's settings) does not match your client's private key.
    • Incorrect Permissions: Strict file permissions are required for ~/.ssh and its contents on both the client and server. Incorrect permissions will often lead to immediate connection termination.
    • Key Not Loaded/Agent Issues: Your private key might not be loaded into your SSH agent, or your ~/.ssh/config might be directing SSH to use the wrong key.
  4. Network Connectivity Issues:
    • Intermittent network instability between your client and the remote server.
    • DNS resolution failures for the remote Git host.
  5. Server Overload or Resource Exhaustion: The remote Git server might be experiencing high CPU, memory, or disk I/O, preventing the sshd daemon from properly processing new connections.
  6. Remote Service Specifics:
    • GitHub/GitLab Rate Limiting: While more often manifesting as an authentication error, extreme rate limiting could potentially lead to connection termination.
    • Temporary Service Outages: The remote Git hosting provider could be experiencing a temporary service interruption.

Step-by-Step Resolution

Follow these steps to diagnose and resolve the "Git SSH connection closed by foreign host" error.

1. Perform Initial Connectivity & SSH Debugging Checks

Before diving deep, verify basic connectivity and gather more verbose SSH output.

  1. Check Network Connectivity:

    ping github.com # Or your remote Git host, e.g., git.example.com
    # Press Ctrl+C to stop
    

    If ping fails, investigate your internet connection, DNS settings (/etc/resolv.conf), or corporate network policies.

  2. Test Raw SSH Connection with Verbose Output: This is crucial for detailed diagnostics.

    ssh -vvv [email protected] # Or git@your_remote_server_ip
    

    Analyze the output carefully. Look for lines like debug1: send_pubkey_test: no mutual signature algorithm, debug1: permanently_drop_suid: 1000, or specific errors indicating authentication failures or connection resets. This will often pinpoint the exact moment the "foreign host" closes the connection.

  3. Check Remote Server's SSH Service Status (If it's your server): If you have administrative access to the remote Git server, check the SSH daemon's status:

    sudo systemctl status sshd
    

    Look for Active: active (running). If it's not running or shows errors, restart it: sudo systemctl restart sshd.

2. Investigate Firewall Rules

Firewalls are a common culprit for connection issues on port 22.

  1. Client-Side Firewall (Your Ubuntu 22.04 Machine): If you're running UFW (Uncomplicated Firewall) locally:

    sudo ufw status
    

    Ensure that outgoing connections on port 22 are allowed. If necessary, you can temporarily disable UFW for testing (but re-enable it immediately after).

    > [!WARNING]
    > Temporarily disabling your firewall can expose your system to security risks. Only do this for quick testing and re-enable it as soon as possible.
    sudo ufw disable # Temporarily disable
    # Retest Git operation
    sudo ufw enable  # Re-enable
    

    If you need to explicitly allow outbound SSH connections, it's usually permitted by default, but if not:

    sudo ufw allow out to any port 22
    
  2. Server-Side Firewall (Remote Git Host): If the remote Git host is your server, check its firewall configuration.

    • UFW:
      sudo ufw status
      
      Ensure 22/tcp is allowed from your client's IP address or Anywhere.
      sudo ufw allow from your_client_ip to any port 22
      # Or, to allow from anywhere (less secure, use only if necessary)
      sudo ufw allow 22/tcp
      
    • iptables:
      sudo iptables -L -v -n
      
      Look for ACCEPT rules on port 22 for tcp protocol.
    • Cloud Provider Security Groups/Network ACLs: If your remote server is hosted on AWS EC2, Google Cloud, Azure, DigitalOcean, etc., check the associated security group or network ACL rules. Ensure inbound TCP traffic on port 22 is allowed from your client's public IP address.

3. Review SSH Server Configuration (sshd_config) on the Remote Host

If you have root access to the remote Git server, inspect its SSH daemon configuration.

  1. Edit sshd_config:

    sudo nano /etc/ssh/sshd_config
    

    Pay close attention to these directives:

    • MaxStartups: This limits concurrent unauthenticated connections. A common value is 10:30:60 (start with 10, drop 30% after 10, max 60). If it's set very low (e.g., 3) and the server is busy, your connection might be dropped. Consider increasing it slightly, e.g., MaxStartups 10:50:100.
    • AllowUsers, DenyUsers: Ensure your username is not explicitly denied or that it's listed in AllowUsers.
    • Protocol: Should be 2. Protocol 2 is standard for modern SSH.
    • ClientAliveInterval / ClientAliveCountMax: These settings prevent connections from timing out, but if configured too aggressively (low values), they could prematurely close connections. Default values are usually fine.
  2. Restart SSH Service:

    > [!IMPORTANT]
    > After modifying `/etc/ssh/sshd_config`, you *must* restart the SSH service for changes to take effect. Always ensure you have another way to access your server (e.g., console access) before restarting SSH, especially if you've made significant changes, to avoid locking yourself out.
    sudo systemctl restart sshd
    

4. Verify SSH Key Authentication

Mismatched or improperly permissioned SSH keys are a very frequent cause.

  1. On your Ubuntu 22.04 Client:

    • Check Key Existence: Ensure your private key exists (e.g., ~/.ssh/id_rsa).
    • Check Key Permissions:
      chmod 700 ~/.ssh
      chmod 600 ~/.ssh/id_rsa # Your private key
      chmod 644 ~/.ssh/id_rsa.pub # Your public key (if present)
      chmod 644 ~/.ssh/known_hosts # If present
      
    • Add Key to SSH Agent:
      eval "$(ssh-agent -s)"
      ssh-add ~/.ssh/id_rsa # Or the path to your specific private key
      
      Run ssh-add -l to verify your key is loaded.
    • Check ~/.ssh/config: If you have custom SSH configurations, ensure they aren't pointing to the wrong key or conflicting with other settings.
      nano ~/.ssh/config
      
      Look for IdentityFile directives. For example:
      Host github.com
          Hostname github.com
          User git
          IdentityFile ~/.ssh/github_rsa
      
      Make sure the IdentityFile path is correct.
  2. On the Remote Git Host (if it's your server):

    • Check authorized_keys Permissions and Content: Log in to the remote server using another method (e.g., password, console) if necessary.
      chmod 700 ~/.ssh
      chmod 600 ~/.ssh/authorized_keys
      
      ls -la ~/.ssh
      cat ~/.ssh/authorized_keys
      
      Ensure the authorized_keys file contains your public key, and that it's on a single line with no extra spaces or line breaks. Also, verify that the owner and group of ~/.ssh and ~/.ssh/authorized_keys belong to the user attempting to log in (e.g., git user for [email protected]).
      sudo chown -R git:git /home/git/.ssh # Adjust user/group as needed
      

5. Analyze SSH Debug Output with Git

To get even more detailed insight when the error occurs during a Git command, you can pass verbose SSH options directly to Git:

GIT_SSH_COMMAND="ssh -vvv" git clone [email protected]:youruser/yourrepo.git

This command will execute ssh -vvv instead of the default ssh when Git performs its operations, providing a flood of debugging information. Carefully review this output for any specific error messages preceding the "Connection closed by foreign host" line, as they will be critical clues.

6. Server Resource Check (Remote Host)

If the remote host is under your control, check for resource exhaustion:

top # Or htop
free -h
df -h
dmesg | grep -i "oom-killer"
journalctl -xe | grep sshd

High CPU, low memory, full disk, or messages from the OOM (Out-Of-Memory) killer in dmesg can indicate that the server is too busy to handle new SSH connections, leading to the connection being dropped.

By systematically working through these steps, you should be able to identify and resolve the underlying cause of the "Git SSH connection closed by foreign host port 22 fatal protocol" error on your Ubuntu 22.04 LTS environment.

👨‍💻

Johnathon Wheeler

Senior Systems Architect & DevOps Engineer • Austin, TX

Connect on LinkedIn →

Johnathon has over 16 years of hands-on experience designing, debugging, and scaling Linux web hosting stacks, container clusters, and high-availability database architectures. Every guide on ButItWorkedLocal is independently tested against Debian 12, Ubuntu 24.04/22.04 LTS, Rocky Linux, and Docker environments to guarantee reproducibility in production.

🛡️

Our Production Verification Guarantee

Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.