Ansible "Permission denied (publickey)" - Fix SSH Auth in CI
By Daniel Zoghalchali·Latchkey
SSH reached the host but rejected authentication - the private key the runner offered is not accepted for the user being used. This is a credentials/config problem, not a network one.
What this error means
Ansible reports the host UNREACHABLE with Permission denied (publickey). The connection itself succeeds (so it is not a timeout), but no offered key authenticates, so every task is skipped. It fails identically on retry.
ansible output
fatal: [db01]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to
the host via ssh: deploy@10.0.4.7: Permission denied (publickey).", "unreachable": true}
Diagnose it: state, credentials, or drift?
Infrastructure failures in CI are usually about state access or credentials rather than the configuration itself. Confirm the runner can reach and lock state before reading the plan output.
The deploy key is not added to the SSH agent or referenced via --private-key, so Ansible has no key to offer. Common when the key lives in a secret that was never written to disk or loaded.
Wrong remote_user or missing public key
The play connects as the wrong user, or the matching public key is not in that user’s authorized_keys on the target, so authentication is refused.
How to fix it
Load the deploy key into the agent
Write the secret key to the agent (or a file) before running the playbook.
Set ansible_user / remote_user to the account whose authorized_keys holds your public key.
Verify manually: ssh -i key deploy@host should succeed before Ansible does.
Confirm the public key is present on the target for that user.
How to prevent it
Store the deploy private key as a CI secret and load it per job.
Pin ansible_user explicitly in inventory so the right account is used.
Use a dedicated, narrowly scoped deploy key rather than a personal key.
Frequently asked questions
What causes Ansible "Permission denied (publickey)"?
There are 2 common causes: private key not loaded in ci and wrong remote_user or missing public key. The deploy key is not added to the SSH agent or referenced via --private-key, so Ansible has no key to offer.
How do I fix Ansible "Permission denied (publickey)"?
There are 2 fixes depending on which cause you have: load the deploy key into the agent and match remote_user and authorized_keys. Work through them in order, since the first is the most common.
What does Ansible "Permission denied (publickey)" actually mean?
Ansible reports the host UNREACHABLE with Permission denied (publickey).
How do I stop Ansible "Permission denied (publickey)" happening again?
Store the deploy private key as a CI secret and load it per job. The prevention section lists 3 changes that keep it from recurring.