When Jenkins fails to authenticate with a Git repository via SSH, the error typically manifests with status code 128 and "Permission denied" messages, even when shell access works. Here's a comprehensive approach to resolving this common CI/CD pipeline issue.
The core error pattern appears as:
Command "/usr/bin/git -c core.askpass=true ls-remote -h git@store:repositories/testproject.git HEAD"
returned status code 128:
Permission denied (publickey,password)
fatal: Could not read from remote repository
First, confirm these critical components:
# Verify Jenkins user's SSH access
sudo -u jenkins ssh -vT git@store
# Check known_hosts entry
sudo -u jenkins cat ~jenkins/.ssh/known_hosts | grep store
# Test direct Git access
sudo -u jenkins git ls-remote git@store:repositories/testproject.git
For Jenkins slaves, implement this credential setup:
1. Navigate to: Jenkins → Manage Jenkins → Manage Credentials
2. Add new "SSH Username with private key" credential
3. Use username: git
4. Paste the private key contents directly OR
5. Select "From the Jenkins master ~/.ssh"
Enable verbose SSH output by modifying your Jenkins job configuration:
# In Jenkins job build environment
export GIT_SSH_COMMAND="ssh -vvv"
# Alternative for older Git versions:
export GIT_TRACE_PACKET=1
export GIT_TRACE=1
export GIT_TRACE_PERFORMANCE=1
For master-slave setups, ensure proper key distribution:
# On master node:
ssh-keygen -t rsa -b 4096 -C "jenkins@store"
ssh-copy-id -i ~jenkins/.ssh/id_rsa.pub jenkins@dilbert
# On each slave node:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
cat >> ~/.ssh/authorized_keys < MASTER_PUBKEY
chmod 600 ~/.ssh/authorized_keys
In Jenkins global configuration:
1. Set global Git config:
git config --global core.sshCommand "ssh -i /var/lib/jenkins/.ssh/id_rsa -F /dev/null"
2. Verify plugin version (minimum 3.0.0 recommended)
3. Configure additional behaviors:
- Advanced clone behaviors
- Sparse checkout paths
- Force polling using workspace
When SSH continues to fail, consider these workarounds:
1. HTTP/HTTPS authentication:
https://username:token@git-server.com/repo.git
2. Deploy keys with restricted access
3. Jenkins credentials binding:
withCredentials([sshUserPrivateKey(
credentialsId: 'git-ssh-key',
keyFileVariable: 'SSH_KEY')]) {
sh 'git -c core.sshCommand="ssh -i $SSH_KEY" clone...'
}
The error occurs when Jenkins attempts to authenticate with a Git repository using SSH, despite working manual SSH access. The key symptoms include:
Permission denied (publickey,password)
fatal: Could not read from remote repository
When Jenkins runs Git operations, it uses a different environment than manual shell access. Here's how to properly set up SSH keys:
- Generate dedicated SSH key for Jenkins:
sudo -u jenkins ssh-keygen -t rsa -b 4096 -C "jenkins@buildserver" # Save to /var/lib/jenkins/.ssh/id_rsa
- Verify key permissions:
chmod 700 /var/lib/jenkins/.ssh chmod 600 /var/lib/jenkins/.ssh/id_rsa chmod 644 /var/lib/jenkins/.ssh/id_rsa.pub
For distributed builds, each slave needs proper SSH configuration:
# On master node:
ssh-copy-id -i /var/lib/jenkins/.ssh/id_rsa.pub jenkins@dilbert
# Test connection:
ssh -vT git@store
Add these build steps to diagnose authentication issues:
# Diagnostic script for Jenkins pipeline
stage('Debug SSH') {
steps {
script {
withCredentials([sshUserPrivateKey(
credentialsId: 'jenkins-git-key',
keyFileVariable: 'SSH_KEY'
)]) {
sh '''
echo "Testing SSH connection..."
ssh -T -i $SSH_KEY -v git@store || true
echo "Testing Git access..."
GIT_SSH_COMMAND="ssh -i $SSH_KEY" git ls-remote git@store:repositories/testproject.git
'''
}
}
}
}
For complex environments, consider these approaches:
- Configure SSH config for Jenkins:
Host store HostName store.yourdomain.com User git IdentityFile /var/lib/jenkins/.ssh/id_rsa StrictHostKeyChecking no
- Use Jenkins credentials binding:
environment { GIT_SSH_COMMAND = 'ssh -i /path/to/private/key' }
After configuration, run these verification commands:
# As Jenkins user
sudo -u jenkins ssh -vT git@store
# Check known_hosts
cat /var/lib/jenkins/.ssh/known_hosts
# Test with full git command
sudo -u jenkins git ls-remote git@store:repositories/testproject.git