The SSH agent refused to sign an authentication challenge with your key. This is usually caused by an ssh-add -c confirmation requirement, a hardware-key touch prompt, or gpg-agent/keyring acting as the agent.
When you connect to a remote host, your SSH client asks the SSH agent (the background process holding your unlocked private keys) to sign a cryptographic challenge that proves you own the key. The message "sign_and_send_pubkey: signing failed for RSA from agent: agent refused operation" means the agent actively declined to perform that signature. Critically, the key is already loaded into the agent at this point, so the on-disk private key file is not what the agent is reading to sign — the unlocked key material lives in the agent's memory. That means file permissions on ~/.ssh/id_rsa are usually NOT the cause of this specific error (a permissions problem typically surfaces earlier, as "WARNING: UNPROTECTED PRIVATE KEY FILE!" or "Bad permissions" before the agent ever holds the key). The agent refuses for reasons such as: the key was added with a confirmation requirement (ssh-add -c) and you did not approve the prompt; the key is backed by a hardware token (YubiKey, smart card, FIDO key) that needs a physical touch; or an alternative agent implementation (gpg-agent, GNOME Keyring, a password manager) is bound to SSH_AUTH_SOCK and is rejecting or mishandling the request.
Start by collecting facts. List what the agent currently holds and watch the negotiation:
ssh-add -l
ssh -v [email protected]In the -v output, look for the line Offering public key: immediately before the agent refused operation message — that tells you exactly which key the agent declined. Also check which agent is bound:
echo "$SSH_AUTH_SOCK"If the socket path points at gpg-agent, gcr/ssh (GNOME Keyring), or a password-manager path rather than /tmp/ssh-XXXX/agent.NNNN, an alternative agent is in control — see step 4.
The most common trigger for agent refused operation is a key added with the confirmation flag, which makes the agent prompt you (via ssh-askpass) before every signature. If you dismissed that prompt, missed it, or are on a session with no GUI askpass, the agent refuses.
Check whether confirmation is the issue by re-adding the key normally (without -c):
ssh-add -d ~/.ssh/id_rsa # remove the existing entry
ssh-add ~/.ssh/id_rsa # re-add WITHOUT -c
ssh-add -l # confirm it is listedIf you intentionally want the confirmation behavior, keep -c but make sure an askpass helper is installed and your SSH_ASKPASS/DISPLAY environment is set so the prompt can actually appear, then approve it when connecting.
If your key lives on a YubiKey, FIDO/U2F authenticator, or smart card, the agent refuses to sign until you physically interact with the device.
Reproduce the connection and watch the device:
ssh -v [email protected]When the token's light blinks (or the OS shows a touch/PIN prompt), tap the key or enter the PIN. For FIDO-backed keys (sk-ssh-ed25519/sk-ecdsa) ensure your OpenSSH client is 8.2+ and the key is loaded:
ssh-add -l # FIDO keys appear with an (FIDO) / sk- prefixIf nothing prompts at all, the middleware may be missing — install your vendor's PKCS#11/PIV middleware and load it with ssh-add -s /path/to/vendor-pkcs11.so.
gpg-agent, GNOME Keyring, KeePassXC, and 1Password can all register themselves as your SSH agent via $SSH_AUTH_SOCK, and each can refuse signing for its own reasons (locked vault, unsupported key type, missing pinentry).
Identify the agent:
ps -o pid,comm -p "$(lsof -t "$SSH_AUTH_SOCK" 2>/dev/null | head -1)" 2>/dev/null
echo "$SSH_AUTH_SOCK"If gpg-agent is acting as the SSH agent, make sure the key's keygrip is authorized in ~/.gnupg/sshcontrol and that pinentry can prompt you; restart it cleanly:
gpgconf --kill gpg-agent
gpg-connect-agent updatestartuptls /byeTo temporarily fall back to the stock OpenSSH agent for one shell and test in isolation:
unset SSH_AUTH_SOCK
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa
ssh -v [email protected]If it works under the plain agent, the alternative agent's configuration is the culprit.
If the agent process crashed or its socket went stale (common after a logout/reconnect), signing fails even though ssh-add -l may still show cached state from your environment.
Restart the stock agent and reload your key:
ssh-agent -k 2>/dev/null # ask the current agent to exit, if reachable
eval "$(ssh-agent -s)" # start a fresh agent and export its env vars
ssh-add ~/.ssh/id_rsa
ssh-add -lNote: ssh-agent -k cleanly terminates the agent referenced by your current environment variables. Avoid blindly pkill ssh-agent if other sessions depend on a shared agent. After restarting, retry the connection.
The agent can only sign with keys it actually holds in unlocked form. Compare what the agent has against the key the server expects:
ssh-add -l # fingerprints currently in the agent
ssh-keygen -lf ~/.ssh/id_rsa.pub # fingerprint of the key you expect to useIf the expected fingerprint is missing, add the key. To reliably detect whether a key file is passphrase-protected across BOTH old PEM and modern OpenSSH key formats, attempt to read it with an empty passphrase — it succeeds only if the key is unencrypted:
ssh-keygen -y -P "" -f ~/.ssh/id_rsa >/dev/null 2>&1 \
&& echo "key is NOT passphrase-protected" \
|| echo "key IS passphrase-protected (or path is wrong)"(head -2 ~/.ssh/id_rsa only reveals the legacy Proc-Type: 4,ENCRYPTED header on old PEM keys; modern -----BEGIN OPENSSH PRIVATE KEY----- files never show it, so do not rely on that check.)
Then load the key, entering the passphrase if prompted:
ssh-add ~/.ssh/id_rsaPermissions are a less likely cause for agent refused operation (the agent already holds the unlocked key), but a misconfigured ~/.ssh can still cause ssh-add to refuse loading a key in the first place, or trigger the UNPROTECTED PRIVATE KEY FILE warning. Verify them:
ls -ld ~/.ssh
ls -l ~/.ssh/id_rsaThe directory should be drwx------ (0700) and the private key -rw------- (0600). Fix if needed:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa ~/.ssh/id_ed25519 ~/.ssh/id_ecdsa 2>/dev/nullThen re-add the key (ssh-add ~/.ssh/id_rsa) and retry.
To prove whether the agent is at fault, connect using the key file directly and ignore the agent for a single command:
ssh -o IdentityAgent=none -o IdentitiesOnly=yes -i ~/.ssh/id_rsa [email protected]If this succeeds while normal connections fail, the problem is definitively in the agent (steps 2–5), not the key itself or the server's authorized_keys.
Use this as a diagnostic, not a permanent setup: disabling the agent forfeits agent forwarding and single-passphrase caching, and you will be prompted for the passphrase on every connection. Fix the underlying agent issue rather than leaving IdentityAgent none in ~/.ssh/config.
gpg-agent as ssh-agent: If you use enable-ssh-support in ~/.gnupg/gpg-agent.conf, every SSH key must have its keygrip listed in ~/.gnupg/sshcontrol, and pinentry must be able to prompt. On headless or remote sessions set GPG_TTY=$(tty) and use a TTY-capable pinentry, or the agent will refuse to sign.
ssh-add key lifetimes: A key added with ssh-add -t <seconds> is automatically dropped when it expires; subsequent signatures are refused until you re-add it. Check expiry behavior if refusals appear only after a period of inactivity.
macOS Keychain: After a reboot the agent may no longer hold an unlocked key. Re-add it to the Keychain with the current flag (-K was deprecated):
ssh-add --apple-use-keychain ~/.ssh/id_rsaAdd AddKeysToAgent yes and UseKeychain yes under the relevant Host block in ~/.ssh/config so the key is reloaded automatically.
SELinux / AppArmor: A confined sshd or agent can have its socket access denied. Inspect audit logs before changing policy, and prefer a targeted boolean or policy module over disabling enforcement:
sudo ausearch -m avc -ts recent | grep -i sshMultiple keys / IdentitiesOnly: If the agent offers the wrong key first the server may reject it before reaching the right one. Pin the correct key per host:
Host github.com
IdentitiesOnly yes
IdentityFile ~/.ssh/github_keyAgent forwarding caution: Forwarding the agent (ssh -A) exposes your loaded keys to the remote host's root/agent socket; a compromised host can sign as you. Prefer ProxyJump (ssh -J) for multi-hop access instead of forwarding the agent.
Windows (WSL / Git Bash): Keys must live at the path the client expects (e.g. C:\Users\USERNAME\.ssh\id_rsa for Git Bash) with NTFS ACLs restricted to your user. The Windows OpenSSH agent service (ssh-agent) and the WSL agent are separate; make sure you are talking to the one that holds your key.
sign_and_send_pubkey: no mutual signature supported
How to fix "sign_and_send_pubkey: no mutual signature supported" in SSH
Bad owner or permissions on /home/user/.ssh/config
How to fix "Bad owner or permissions on .ssh/config" in SSH
No more authentication methods to try.
How to fix "No more authentication methods to try." in SSH
Error connecting to agent: Connection refused
How to fix "Error connecting to agent: Connection refused" in SSH
bind: Address already in use
How to fix "bind: Address already in use" in SSH