Fixing the Ansible 'REMOTE HOST IDENTIFICATION HAS CHANGED' SSH Error

beginner๐Ÿ”ง Ansible2026-05-24| Ansible 2.9+, Linux (Ubuntu/CentOS/Debian), macOS, SSH-based connections.

Error Message

WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
#ansible#ssh#known_hosts#devops#security

TL;DR: The Quick Fix

If you need to resume work immediately and understand the security trade-offs (common in local labs or dev environments), run this command to wipe the old host key:

ssh-keygen -R <your_server_ip_or_hostname>

Alternatively, you can tell Ansible to stop checking keys globally by adding this to your ansible.cfg:

[defaults]
host_key_checking = False

Understanding the Alarm

You run a playbook and everything stops. A block of red text warns you that the remote host identification has changed. This isn't a bug in Ansible; it is a fundamental SSH security mechanism.

SSH uses a "fingerprint" to verify server identity. On your first connection, this fingerprint is saved to ~/.ssh/known_hosts. If you later reinstall the OS, or if a cloud provider assigns a recycled IP to a new instance, the fingerprint changes. SSH detects this mismatch and kills the connection to prevent a Man-In-The-Middle (MITM) attack.

Solution 1: Scrubbing the Stale Key (Most Secure)

This is the surgical approach. Instead of lowering your guard, you simply tell your machine to forget the outdated fingerprint for one specific IP or hostname.

# Replace 192.168.1.100 with the IP of your target server
ssh-keygen -R 192.168.1.100

Next time you run Ansible, it will treat the server as a new connection. You may need to manually SSH in once to type "yes" and accept the new key, or use the automation methods below.

Solution 2: Bypassing Checks for Dynamic Scaling

Manually clearing keys is fine for one or two servers. However, if you are spinning up 50 ephemeral AWS EC2 instances a day, it becomes an impossible bottleneck. You can automate the bypass.

Option A: Project-Level Config (Recommended)

Create an ansible.cfg file in your project root. This ensures the setting stays with your project and doesn't affect your entire system.

[defaults]
host_key_checking = False

Option B: Use an Environment Variable

Need a one-time fix without editing files? Set the variable directly in your terminal session:

export ANSIBLE_HOST_KEY_CHECKING=False
ansible-playbook deploy.yml

Option C: Deep SSH Customization

For more control, pass arguments directly to the underlying SSH process. This configuration prevents Ansible from writing anything to your known_hosts file at all:

[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null

Solution 3: Self-Healing Playbooks

You can handle the keys dynamically within your automation logic. Use the known_hosts module to fetch and authorize the new key before running the rest of your tasks.

- name: Auto-accept new SSH fingerprints
  hosts: localhost
  tasks:
    - name: Scan and update known_hosts
      known_hosts:
        name: "{{ target_ip }}"
        key: "{{ lookup('pipe', 'ssh-keyscan -t rsa ' + target_ip) }}"
        state: present

Verifying the Fix

Test your connection with the ping module. A successful fix will return a bright green "pong" without asking for manual confirmation.

ansible all -m ping -i inventory.ini

If it still fails, check for duplicate entries. Occasionally, known_hosts contains entries for both the hostname and the IP address separately; you'll need to run ssh-keygen -R for both.

Final Security Considerations

  • Context Matters: Disabling host key checking is standard practice for CI/CD pipelines and internal VPCs. It saves hours of troubleshooting.
  • Public Risks: Avoid disabling this for production servers accessed over the open internet. Without key verification, you have no way to ensure your data isn't being intercepted by a malicious gateway.
  • Refer to the Official Ansible Docs for advanced security tuning.

Related Error Notes