Resolve SSH authentication errors when the SSH agent refuses to sign public keys. This tutorial covers checking agent status, fixing key permissions, restarting the agent, and troubleshooting SSH client configuration.
Prerequisites
- Basic command line knowledge
- SSH client installed
- Existing SSH key pair
What this solves
The "sign_and_send_pubkey: signing failed: agent refused operation" error occurs when your SSH client cannot authenticate using public key authentication. This typically happens when the SSH agent is not running, cannot access your private keys, or when key permissions are incorrect. This tutorial shows you how to diagnose and fix these SSH authentication issues.
Understanding the SSH agent refused operation error
This error appears in several scenarios. Your SSH agent might not be running, your private keys might not be loaded into the agent, or file permissions on your SSH keys could be too permissive. The SSH agent is a background process that holds your private keys in memory and handles authentication requests from SSH clients.
When you see this error, SSH falls back to other authentication methods like password authentication. If that's also disabled, you'll get locked out of your server. The key is identifying whether the problem is with the agent, the keys, or the SSH client configuration.
Step-by-step troubleshooting
Check SSH agent status
First, verify that the SSH agent is running and accessible. The SSH_AUTH_SOCK environment variable should point to the agent's socket file.
echo $SSH_AUTH_SOCK
ps aux | grep ssh-agent
If SSH_AUTH_SOCK is empty or the agent process isn't running, you need to start the SSH agent.
Start SSH agent if not running
If no agent is running, start it and set the environment variables. This command starts the agent and outputs the variables you need to set.
eval $(ssh-agent -s)
echo "SSH agent started with PID: $SSH_AGENT_PID"
The eval command sets SSH_AUTH_SOCK and SSH_AGENT_PID in your current shell session.
Check loaded SSH keys
List the keys currently loaded in the SSH agent. If no keys are loaded, the agent cannot authenticate you.
ssh-add -l
If you see "The agent has no identities", your keys aren't loaded. If you see "Could not open a connection to your authentication agent", the agent isn't properly configured.
Load SSH keys into agent
Add your private keys to the SSH agent. By default, ssh-add looks for common key names in ~/.ssh/.
ssh-add ~/.ssh/id_rsa
ssh-add ~/.ssh/id_ed25519
ssh-add -l
Replace the key paths with your actual key files. The last command confirms your keys are now loaded.
Fix SSH key permissions
SSH is strict about key file permissions. Private keys must be readable only by you, and the ~/.ssh directory must have restricted access.
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_rsa.pub
chmod 644 ~/.ssh/id_ed25519.pub
Check SSH key ownership
Ensure you own all SSH key files. If keys were created by another user or copied incorrectly, SSH will reject them.
ls -la ~/.ssh/
whoami
If the owner isn't your username, fix it:
sudo chown -R $USER:$USER ~/.ssh/
Restart SSH agent and reload keys
Sometimes the agent gets into a bad state. Kill existing agents and start fresh.
ssh-agent -k
eval $(ssh-agent -s)
ssh-add ~/.ssh/id_rsa
ssh-add ~/.ssh/id_ed25519
This ensures you have a clean agent with properly loaded keys.
Test SSH connection
Try connecting to your server with verbose output to see the authentication process.
ssh -v user@your-server.example.com
Look for lines mentioning "Offering public key" and "Server accepts key". If you still see the agent error, check the SSH client configuration.
Troubleshoot SSH client configuration
Check SSH config file
Your SSH client configuration might be interfering with agent communication. Check for conflicting settings.
cat ~/.ssh/config
Look for these potentially problematic settings:
# These can cause agent issues
IdentitiesOnly yes
PubkeyAuthentication no
ForwardAgent no
Fix SSH config conflicts
If you have a restrictive SSH config, ensure it allows agent forwarding and public key authentication for your server.
Host your-server.example.com
HostName your-server.example.com
User your-username
PubkeyAuthentication yes
IdentitiesOnly no
ForwardAgent yes
Save the file and test the connection again.
Clear SSH known_hosts if needed
Sometimes SSH key conflicts in known_hosts can cause authentication issues. Remove the server's entry if you've reinstalled it.
ssh-keygen -R your-server.example.com
This removes any old host key entries that might conflict with the current server.
Configure automatic SSH agent startup
Add agent to shell profile
To avoid manually starting the agent each time, add it to your shell's startup file. This ensures the agent runs automatically when you log in.
# Start SSH agent if not already running
if [ -z "$SSH_AUTH_SOCK" ]; then
eval $(ssh-agent -s)
ssh-add ~/.ssh/id_rsa ~/.ssh/id_ed25519 2>/dev/null
fi
Source your shell profile to apply changes:
source ~/.bashrc
Use keychain for persistent agent
Install keychain to manage SSH agent across sessions more reliably.
sudo apt update && sudo apt install -y keychain
Add keychain to your shell profile:
eval $(keychain --eval --agents ssh id_rsa id_ed25519)
Verify your setup
Test that your SSH agent setup works correctly:
# Check agent is running
echo $SSH_AUTH_SOCK
ssh-add -l
Test connection
ssh -v user@your-server.example.com
Check key permissions
ls -la ~/.ssh/
You should see your keys listed by ssh-add -l, and the SSH connection should succeed without the agent error.
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| "Could not open a connection" | SSH agent not running | eval $(ssh-agent -s) |
| "The agent has no identities" | No keys loaded | ssh-add ~/.ssh/id_rsa |
| "Permissions 0644 too open" | Private key too permissive | chmod 600 ~/.ssh/id_rsa |
| Agent starts but keys won't load | Wrong key ownership | chown $USER ~/.ssh/id_rsa |
| Works in terminal, fails in scripts | Missing environment variables | Source agent variables in script |
| Keys load but authentication fails | Wrong public key on server | Check ~/.ssh/authorized_keys on server |
Prevention and best practices
Always verify key permissions after copying keys between systems. Use ssh-copy-id to install public keys on remote servers instead of manually copying them. This command ensures correct permissions and placement.
Consider using SSH certificates for large environments instead of managing individual public keys. For more advanced SSH security, you might want to explore SSH tunneling and port forwarding or advanced SSH key authentication.
Monitor SSH authentication logs in /var/log/auth.log (Ubuntu/Debian) or /var/log/secure (RHEL-based systems) to catch authentication issues early.
Next steps
- Configure SSH key authentication and disable password login
- Set up SSH port forwarding and tunneling
- Configure SSH certificate authentication for enterprise use
- Set up SSH bastion host for secure remote access
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# SSH Key Authentication Fix Script
# Fixes "sign_and_send_pubkey: signing failed: agent refused operation" error
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Progress tracking
TOTAL_STEPS=8
CURRENT_STEP=0
progress() {
((CURRENT_STEP++))
echo -e "${GREEN}[$CURRENT_STEP/$TOTAL_STEPS]${NC} $1"
}
error() {
echo -e "${RED}ERROR:${NC} $1" >&2
}
warning() {
echo -e "${YELLOW}WARNING:${NC} $1"
}
success() {
echo -e "${GREEN}SUCCESS:${NC} $1"
}
usage() {
cat << EOF
Usage: $0 [OPTIONS]
Fix SSH key authentication issues
OPTIONS:
-u, --user USER Target user (default: current user)
-k, --key-type TYPE Key type to create if missing (rsa|ed25519, default: ed25519)
-h, --help Show this help message
Examples:
$0 Fix SSH for current user
$0 -u myuser Fix SSH for specific user
$0 -k rsa Create RSA key if missing
EOF
exit 1
}
cleanup() {
if [ $? -ne 0 ]; then
error "Script failed. SSH agent may be in inconsistent state."
warning "You may need to run 'ssh-agent -k' and restart your shell session"
fi
}
trap cleanup ERR
# Default values
TARGET_USER="${SUDO_USER:-$USER}"
KEY_TYPE="ed25519"
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
-u|--user)
TARGET_USER="$2"
shift 2
;;
-k|--key-type)
if [[ "$2" =~ ^(rsa|ed25519)$ ]]; then
KEY_TYPE="$2"
else
error "Invalid key type. Use 'rsa' or 'ed25519'"
exit 1
fi
shift 2
;;
-h|--help)
usage
;;
*)
error "Unknown option: $1"
usage
;;
esac
done
# Detect distribution
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
;;
almalinux|rocky|centos|rhel|ol)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
;;
fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
;;
*)
error "Unsupported distribution: $ID"
exit 1
;;
esac
else
error "Cannot detect distribution"
exit 1
fi
# Check if user exists
if ! id "$TARGET_USER" &>/dev/null; then
error "User '$TARGET_USER' does not exist"
exit 1
fi
# Get user home directory
TARGET_HOME=$(eval echo "~$TARGET_USER")
SSH_DIR="$TARGET_HOME/.ssh"
progress "Checking prerequisites and installing required packages"
if ! command -v ssh-keygen &> /dev/null; then
if [ "$EUID" -eq 0 ]; then
$PKG_INSTALL openssh-clients openssh-server
else
error "ssh-keygen not found. Please run with sudo to install openssh packages"
exit 1
fi
fi
progress "Creating SSH directory and setting up structure"
# Create SSH directory if it doesn't exist
if [ ! -d "$SSH_DIR" ]; then
if [ "$EUID" -eq 0 ]; then
mkdir -p "$SSH_DIR"
chown "$TARGET_USER:$(id -gn "$TARGET_USER")" "$SSH_DIR"
else
mkdir -p "$SSH_DIR"
fi
fi
# Set correct permissions for SSH directory
chmod 700 "$SSH_DIR"
progress "Checking and fixing SSH key permissions"
# Fix permissions for existing keys
for key_file in "$SSH_DIR"/id_*; do
if [ -f "$key_file" ]; then
if [[ "$key_file" == *.pub ]]; then
chmod 644 "$key_file"
else
chmod 600 "$key_file"
fi
if [ "$EUID" -eq 0 ]; then
chown "$TARGET_USER:$(id -gn "$TARGET_USER")" "$key_file"
fi
fi
done
progress "Checking for existing SSH keys"
# Define key paths based on key type
if [ "$KEY_TYPE" = "ed25519" ]; then
PRIVATE_KEY="$SSH_DIR/id_ed25519"
PUBLIC_KEY="$SSH_DIR/id_ed25519.pub"
else
PRIVATE_KEY="$SSH_DIR/id_rsa"
PUBLIC_KEY="$SSH_DIR/id_rsa.pub"
fi
# Generate key if it doesn't exist
if [ ! -f "$PRIVATE_KEY" ]; then
warning "SSH key not found. Generating new $KEY_TYPE key..."
if [ "$KEY_TYPE" = "ed25519" ]; then
sudo -u "$TARGET_USER" ssh-keygen -t ed25519 -f "$PRIVATE_KEY" -N "" -C "$TARGET_USER@$(hostname)"
else
sudo -u "$TARGET_USER" ssh-keygen -t rsa -b 4096 -f "$PRIVATE_KEY" -N "" -C "$TARGET_USER@$(hostname)"
fi
chmod 600 "$PRIVATE_KEY"
chmod 644 "$PUBLIC_KEY"
success "Generated new SSH key: $PRIVATE_KEY"
fi
progress "Stopping existing SSH agents"
# Kill existing SSH agents for the user
pkill -u "$TARGET_USER" ssh-agent 2>/dev/null || true
progress "Starting SSH agent and loading keys"
# Start SSH agent and load keys
AGENT_OUTPUT=$(sudo -u "$TARGET_USER" ssh-agent -s)
eval "$AGENT_OUTPUT"
# Export agent variables for the target user
sudo -u "$TARGET_USER" -H bash -c "
export SSH_AUTH_SOCK='$SSH_AUTH_SOCK'
export SSH_AGENT_PID='$SSH_AGENT_PID'
ssh-add '$PRIVATE_KEY' 2>/dev/null
"
progress "Configuring SSH client settings"
# Create or update SSH config
SSH_CONFIG="$SSH_DIR/config"
if [ ! -f "$SSH_CONFIG" ]; then
sudo -u "$TARGET_USER" touch "$SSH_CONFIG"
chmod 600 "$SSH_CONFIG"
fi
# Ensure SSH config has proper settings
if ! grep -q "PubkeyAuthentication yes" "$SSH_CONFIG" 2>/dev/null; then
echo "PubkeyAuthentication yes" >> "$SSH_CONFIG"
fi
if ! grep -q "AddKeysToAgent yes" "$SSH_CONFIG" 2>/dev/null; then
echo "AddKeysToAgent yes" >> "$SSH_CONFIG"
fi
progress "Performing verification checks"
# Verify SSH agent is working
if sudo -u "$TARGET_USER" -H bash -c "export SSH_AUTH_SOCK='$SSH_AUTH_SOCK'; ssh-add -l" &>/dev/null; then
success "SSH agent is running and keys are loaded"
else
warning "SSH agent verification failed, but keys should work for new sessions"
fi
# Verify key permissions
PRIVATE_PERMS=$(stat -c %a "$PRIVATE_KEY")
PUBLIC_PERMS=$(stat -c %a "$PUBLIC_KEY")
if [ "$PRIVATE_PERMS" = "600" ] && [ "$PUBLIC_PERMS" = "644" ]; then
success "SSH key permissions are correct"
else
error "SSH key permissions are incorrect"
exit 1
fi
# Create agent startup script for user sessions
BASHRC="$TARGET_HOME/.bashrc"
AGENT_SCRIPT='
# SSH Agent auto-start
if [ -z "$SSH_AUTH_SOCK" ]; then
eval $(ssh-agent -s) >/dev/null
ssh-add ~/.ssh/id_* 2>/dev/null
fi'
if [ -f "$BASHRC" ] && ! grep -q "SSH Agent auto-start" "$BASHRC"; then
echo "$AGENT_SCRIPT" >> "$BASHRC"
success "Added SSH agent auto-start to .bashrc"
fi
echo
success "SSH key authentication has been fixed!"
echo -e "${GREEN}Summary:${NC}"
echo "- SSH directory: $SSH_DIR (permissions: 700)"
echo "- Private key: $PRIVATE_KEY (permissions: 600)"
echo "- Public key: $PUBLIC_KEY (permissions: 644)"
echo "- SSH agent: Running (PID: ${SSH_AGENT_PID:-N/A})"
echo
echo -e "${YELLOW}Next steps:${NC}"
echo "1. Start a new shell session or run: source ~/.bashrc"
echo "2. Test SSH connection: ssh -v user@hostname"
echo "3. If connecting to a new server, copy your public key:"
echo " ssh-copy-id user@hostname"
Review the script before running. Execute with: bash install.sh