AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Ansible 'Failed to Connect via SSH localhost:22': Fix Guide

By Luca Berton · Published 2024-01-01 · Category: installation

Fix Ansible 'failed to connect to the host via ssh localhost port 22' error. Resolve SSH config, connection type, host key, and authentication issues.

Ansible 'Failed to Connect via SSH localhost:22': Fix Guide

Introduction

In today's episode of Ansible Pilot, I'm Luca Berton, and we'll delve into Ansible troubleshooting, focusing on the common error "Failed to connect to the host via SSH: localhost port 22." This error often occurs when testing your code on your local machine using the ansible_connection local parameter.

See also: Ansible SSH with Passwords: Fix sshpass & Authentication (Guide)

Understanding the Error

The exact error message you might encounter in the terminal is:

fatal: [localhost]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via SSH: ssh: connect to host localhost port 22: Connection refused", "unreachable": true}

This error is a clear indication that Ansible failed to establish an SSH connection to the localhost on port 22.

Live Demo

Let's jump into a live Playbook to reproduce the Ansible connection failed problem and fix it in the inventory file.

Error Code: ping.yml

---
- name: ping module Playbook
  hosts: all
  tasks:
    - name: test connection
      ansible.builtin.ping:

Error Execution

Executing the playbook with the error:

$ ansible-playbook -i inventory ping.yml
PLAY [ping module Playbook] *****************************************************************
TASK [Gathering Facts] ******************************************************************
fatal: [localhost]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via SSH: ssh: connect to host localhost port 22: Connection refused", "unreachable": true}
PLAY RECAP ******************************************************************************
localhost                  : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0

Fix Code: ping.yml

---
- name: ping module Playbook
  hosts: all
  tasks:
    - name: test connection
      ansible.builtin.ping:

Fix Execution

Executing the fixed playbook:

$ ansible-playbook -i inventory ping.yml
PLAY [ping module Playbook] *****************************************************************
TASK [Gathering Facts] ******************************************************************
[WARNING]: Platform darwin on host localhost is using the discovered Python interpreter
at /opt/homebrew/bin/python3.10, but future installation of another Python interpreter
could change the meaning of that path. See https://docs.ansible.com/ansible-
core/2.13/reference_appendices/interpreter_discovery.html for more information.
ok: [localhost]
TASK [test connection] ******************************************************************
ok: [localhost]
PLAY RECAP ******************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

See also: Ansible 'Connection failed' Error: Fix SSH & WinRM Issues (Guide)

Links

Local playbooks

Conclusion

In conclusion, you now know how to troubleshoot the common Ansible error "Failed to connect to the host via SSH localhost port 22." By modifying the inventory file and setting ansible_connection=local, you can resolve this issue when testing Ansible code on your local machine.

If you found this troubleshooting guide helpful, be sure to subscribe for more Ansible insights.

See also: Ansible troubleshooting - Destination does not exist rc 257

The Fix: Use Local Connection

# Method 1: In playbook
- hosts: localhost
  connection: local
  tasks:
    - debug: msg="Running locally"

# Method 2: In inventory # inventory.yml all: hosts: localhost: ansible_connection: local

Why It Happens

Ansible defaults to SSH connections. When targeting localhost, it tries to SSH to 127.0.0.1:22, which fails if: SSH server isn't installed/running Port 22 is blocked SSH key not configured for local user No SSH server needed (running locally)

Fix for Remote Host SSH Failures

Check SSH connectivity

# Test SSH manually
ssh user@remote-host -p 22

# Test with Ansible verbosity ansible all -i "remote-host," -m ping -vvvv

Common fixes

# Wrong port
ansible_port: 2222

# Wrong user ansible_user: deploy

# SSH key ansible_ssh_private_key_file: ~/.ssh/deploy_key

# Password auth ansible_password: "{{ vault_ssh_password }}"

# Disable host key checking (dev only) ansible_ssh_common_args: '-o StrictHostKeyChecking=no'

ansible.cfg Settings

[defaults]
host_key_checking = False
timeout = 30

[ssh_connection] ssh_args = -o ControlMaster=auto -o ControlPersist=60s pipelining = True retries = 3

Troubleshooting Checklist

| Check | Command | |-------|---------| | SSH service running | systemctl status sshd | | Port open | ss -tlnp | grep 22 | | Firewall allows SSH | iptables -L -n | grep 22 | | Key permissions | ls -la ~/.ssh/ (should be 600) | | DNS resolution | nslookup remote-host | | Network reachable | ping remote-host |

SSH Timeout Issues

# ansible.cfg
[ssh_connection]
timeout = 60
ssh_args = -o ConnectTimeout=30 -o ServerAliveInterval=15
# Per host
ansible_ssh_common_args: '-o ConnectTimeout=30'

Jump Host / Bastion

# Connect through bastion
ansible_ssh_common_args: '-o ProxyJump=bastion-user@bastion-host'

FAQ

Why does ansible localhost -m ping fail?

If no inventory defines localhost with ansible_connection: local, Ansible tries SSH. Use:

ansible localhost -m ping -c local

How do I fix "Permission denied (publickey)"?

Check key: ssh-add -l Check remote authorized_keys: ~/.ssh/authorized_keys Check key permissions: chmod 600 ~/.ssh/id_rsa Try with password: --ask-pass

SSH works manually but Ansible fails?

Check if Ansible uses a different user (-u), different key, or different SSH config. Run with -vvvv to see the exact SSH command.

The Error

fatal: [localhost]: UNREACHABLE! => {"msg": "Failed to connect to the host via ssh: ssh: connect to host localhost port 22: Connection refused"}

Quick Fix: Use Local Connection

# Playbook
- hosts: localhost
  connection: local  # Don't use SSH for localhost!
  tasks:
    - debug: msg="Works!"
# Or in inventory
localhost ansible_connection=local

Common Causes & Fixes

SSH Not Running

# Check SSH service
systemctl status sshd

# Start it sudo systemctl start sshd sudo systemctl enable sshd

# Install if missing sudo apt install openssh-server # Debian/Ubuntu sudo dnf install openssh-server # RHEL/Rocky

Wrong Port

# If SSH runs on non-standard port
web1:
  ansible_host: 192.168.1.10
  ansible_port: 2222

Host Key Verification Failed

# Error: Host key verification failed
# Fix 1: Accept the key
ssh-keyscan -H target-host >> ~/.ssh/known_hosts

# Fix 2: Disable checking (dev only!) export ANSIBLE_HOST_KEY_CHECKING=False

# ansible.cfg (not for production)
[defaults]
host_key_checking = False

Authentication Failure

# Test SSH manually first
ssh user@target-host

# Specify key ansible all -m ping --private-key ~/.ssh/deploy_key

# Or in inventory web1: ansible_ssh_private_key_file: ~/.ssh/deploy_key ansible_user: deploy

Firewall Blocking

# Check if port is open
nc -zv target-host 22
telnet target-host 22

# Open firewall sudo ufw allow 22 # Ubuntu sudo firewall-cmd --add-service=ssh --permanent # RHEL

Debugging SSH Issues

# Verbose SSH output
ansible all -m ping -vvvv

# Test SSH directly ssh -vvv user@target-host

# Check ansible config ansible-config dump | grep -i ssh

Connection Types

# Local (no SSH needed)
localhost:
  ansible_connection: local

# SSH (default for remote) web1: ansible_connection: ssh

# Docker container1: ansible_connection: docker ansible_host: my-container

# Windows win1: ansible_connection: winrm

SSH Timeout

# ansible.cfg
[ssh_connection]
timeout = 30
retries = 3
ssh_args = -o ConnectTimeout=30 -o ConnectionAttempts=3

Common SSH Error Reference

| Error | Cause | Fix | |-------|-------|-----| | Connection refused | SSH not running / wrong port | Start sshd, check port | | Permission denied | Wrong key/password | Check credentials | | Host key verification | Unknown host | ssh-keyscan or disable check | | Connection timed out | Firewall / network | Check connectivity | | No route to host | Network unreachable | Check IP and routing | | Too many auth failures | Too many keys tried | Specify key with -i |

FAQ

Why does localhost need SSH?

By default, Ansible uses SSH for all hosts. For localhost, set ansible_connection=local to avoid SSH entirely.

Can I use SSH for localhost?

Yes, if SSH is running. But connection: local is faster and simpler for the control node.

"Permission denied (publickey)" — what now?

Your SSH key isn't authorized on the remote host. Copy it with: ssh-copy-id user@host

Related Articles

static and dynamic Ansible inventory

See also

Fix Ansible "UNREACHABLE" Error: Host Connection Troubleshooting

Category: installation

Watch the video: Ansible 'Failed to Connect via SSH localhost:22': Fix Guide — Video Tutorial

Browse all Ansible tutorials · AnsiblePilot Home