This error occurs when Git cannot authenticate your SSH connection to a remote repository like GitHub, GitLab, or Bitbucket. The fix involves generating an SSH key, adding it to your SSH agent, and registering the public key with your Git hosting provider.
This error indicates that the remote Git server (such as GitHub, GitLab, or Bitbucket) rejected your SSH connection because it couldn't verify your identity using SSH public key authentication. When you try to clone, push, pull, or fetch from a remote repository using an SSH URL (like `[email protected]:user/repo.git`), Git uses SSH to establish a secure connection. SSH authentication requires a cryptographic key pair: a private key stored on your machine and a public key registered with the Git hosting service. If the server cannot find a matching public key for the private key you're presenting, or if you don't have any SSH keys configured, you'll see this "Permission denied (publickey)" error. The "fatal: Could not read from remote repository" message confirms that Git was unable to access the repository at all because the authentication step failed before any repository access could occur.
First, verify your SSH connection to the Git host:
# For GitHub
ssh -T [email protected]
# For GitLab
ssh -T [email protected]
# For Bitbucket
ssh -T [email protected]Expected successful response from GitHub:
Hi username! You've successfully authenticated, but GitHub does not provide shell access.If you see "Permission denied (publickey)", continue with the next steps.
For verbose output (helpful for debugging):
ssh -vT [email protected]Look for lines like:
- Offering public key - SSH found a key to try
- No identities found - No SSH keys available
See if you already have SSH keys generated:
# List files in your SSH directory
ls -la ~/.ssh
# Look for these files:
# id_ed25519, id_ed25519.pub (Ed25519 - recommended)
# id_rsa, id_rsa.pub (RSA - older but still valid)
# id_ecdsa, id_ecdsa.pub (ECDSA)If you see key files (a pair with and without .pub extension), you have SSH keys. If the .ssh directory doesn't exist or is empty, you need to generate new keys.
Check if keys are loaded in the agent:
# Start the SSH agent
eval "$(ssh-agent -s)"
# List loaded keys
ssh-add -l
# If empty: "The agent has no identities."If you don't have SSH keys, generate a new key pair:
# Generate Ed25519 key (recommended - more secure and faster)
ssh-keygen -t ed25519 -C "[email protected]"
# Or generate RSA key (for older systems that don't support Ed25519)
ssh-keygen -t rsa -b 4096 -C "[email protected]"When prompted:
- File location: Press Enter to accept the default (~/.ssh/id_ed25519)
- Passphrase: Enter a secure passphrase (recommended) or press Enter for no passphrase
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/you/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/you/.ssh/id_ed25519
Your public key has been saved in /home/you/.ssh/id_ed25519.pubThe SSH agent manages your keys and handles authentication:
# Start the SSH agent in the background
eval "$(ssh-agent -s)"
# Output: Agent pid 12345
# Add your private key to the agent
ssh-add ~/.ssh/id_ed25519
# Or for RSA keys:
ssh-add ~/.ssh/id_rsaIf you set a passphrase, you'll be prompted to enter it when adding the key.
On macOS, to persist the key across restarts:
# Add to keychain (macOS only)
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
# Add this to ~/.ssh/config to auto-load keys:
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519Verify the key is loaded:
ssh-add -l -E sha256Copy your public key to the clipboard:
# macOS
cat ~/.ssh/id_ed25519.pub | pbcopy
# Linux (with xclip)
cat ~/.ssh/id_ed25519.pub | xclip -selection clipboard
# Windows (Git Bash)
cat ~/.ssh/id_ed25519.pub | clip
# Or just display it and copy manually
cat ~/.ssh/id_ed25519.pubFor GitHub:
1. Go to https://github.com/settings/keys
2. Click "New SSH key"
3. Give it a descriptive title (e.g., "Work Laptop")
4. Paste your public key
5. Click "Add SSH key"
For GitLab:
1. Go to https://gitlab.com/-/profile/keys
2. Paste your public key
3. Set an expiration date (optional)
4. Click "Add key"
For Bitbucket:
1. Go to Personal settings > SSH keys
2. Click "Add key"
3. Paste your public key
4. Click "Add key"
Test the SSH connection again:
ssh -T [email protected]Expected success message:
Hi username! You've successfully authenticated, but GitHub does not provide shell access.Now test a git operation:
# Clone a repository
git clone [email protected]:username/repository.git
# Or if you have an existing repo, test fetch
git fetch originIf you still see errors, check the troubleshooting steps below.
If you saved your key with a custom name or have multiple keys, create an SSH config file:
# Create or edit SSH config
nano ~/.ssh/configExample configuration:
# GitHub account
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/github_key
IdentitiesOnly yes
# GitLab account
Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/gitlab_key
IdentitiesOnly yes
# Personal GitHub (for multiple accounts)
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
IdentitiesOnly yesUsing the personal GitHub alias:
git clone git@github-personal:username/repo.gitSet correct permissions on the config file:
chmod 600 ~/.ssh/configSSH requires strict permissions on key files. If permissions are too open, SSH will refuse to use the key:
# Set correct permissions
chmod 700 ~/.ssh # Directory: owner only
chmod 600 ~/.ssh/id_ed25519 # Private key: owner read/write only
chmod 644 ~/.ssh/id_ed25519.pub # Public key: owner read/write, others read
chmod 600 ~/.ssh/config # Config: owner read/write only
# Verify permissions
ls -la ~/.ssh
# Should show: drwx------ for .ssh
# Should show: -rw------- for private keysCommon permission error messages:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/home/user/.ssh/id_ed25519' are too open.If SSH is blocked or you prefer not to use it, switch to HTTPS authentication:
# Clone using HTTPS
git clone https://github.com/username/repository.git
# Change existing remote from SSH to HTTPS
git remote set-url origin https://github.com/username/repository.git
# Verify the change
git remote -vFor HTTPS authentication, use a Personal Access Token (PAT):
1. Generate a token at https://github.com/settings/tokens
2. Select appropriate scopes (repo access)
3. Use the token as your password when prompted
Cache HTTPS credentials:
# Cache credentials for 1 hour (3600 seconds)
git config --global credential.helper 'cache --timeout=3600'
# On macOS, use the keychain
git config --global credential.helper osxkeychain
# On Windows, use the credential manager
git config --global credential.helper manager### Avoid Using sudo with Git
Never use sudo with git commands when working with SSH:
# Wrong - uses root's SSH keys
sudo git clone [email protected]:user/repo.git
# Correct - uses your SSH keys
git clone [email protected]:user/repo.gitThe root user has a different home directory (/root) and therefore different SSH keys than your user account.
### Using SSH Over HTTPS Port (443)
If your network blocks SSH on port 22, GitHub allows SSH connections over port 443:
# Test if port 443 works
ssh -T -p 443 [email protected]
# Add to ~/.ssh/config
Host github.com
HostName ssh.github.com
Port 443
User git
IdentityFile ~/.ssh/id_ed25519### SSH Agent Forwarding
To use your local SSH keys on a remote server:
# Connect with agent forwarding
ssh -A user@remote-server
# On the remote server, git commands will use your forwarded keys
git clone [email protected]:user/repo.gitSecurity note: Only use agent forwarding with servers you trust.
### Debugging SSH Connections
Use verbose mode to diagnose issues:
# Increasing verbosity levels
ssh -v [email protected] # Basic debug
ssh -vv [email protected] # More detail
ssh -vvv [email protected] # Maximum verbosityLook for:
- Authentications that can continue: publickey
- Offering public key: /path/to/key
- Server accepts key: /path/to/key
- Authentication succeeded (publickey)
### Multiple GitHub Accounts
If you have multiple GitHub accounts (e.g., personal and work):
# ~/.ssh/config
Host github.com-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
Host github.com-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personalClone using the host alias:
git clone [email protected]:company/repo.git### Deploy Keys for CI/CD
For servers and CI/CD pipelines, use deploy keys instead of personal SSH keys:
1. Generate a dedicated key pair for the server
2. Add the public key as a Deploy Key in the repository settings
3. Deploy keys can be read-only or read-write per repository
### SSH Key Types Comparison
| Type | Command | Security | Compatibility |
|------|---------|----------|---------------|
| Ed25519 | ssh-keygen -t ed25519 | Excellent | Modern systems |
| RSA 4096 | ssh-keygen -t rsa -b 4096 | Good | Universal |
| ECDSA | ssh-keygen -t ecdsa -b 521 | Good | Most systems |
Ed25519 is recommended for new keys due to better security and smaller key size.
### Regenerating Known Hosts
If you see a host key verification error:
# Remove old host key
ssh-keygen -R github.com
# Reconnect to add new key
ssh -T [email protected]
# Type 'yes' to accept the new fingerprintVerify the fingerprint matches GitHub's published fingerprints before accepting.
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