Introduction
When Ansible fails, the error message usually tells you exactly what's wrong — if you know where to look. This guide covers the most common errors, what causes them, and how to fix them.
Debugging Techniques
Verbose Mode
# Increasing verbosity
ansible-playbook site.yml -v # Basic
ansible-playbook site.yml -vv # More detail
ansible-playbook site.yml -vvv # SSH debugging
ansible-playbook site.yml -vvvv # Maximum (connection debug)
Debug Module
- name: Print variable
ansible.builtin.debug:
var: my_variable
- name: Print message
ansible.builtin.debug:
msg: "Host {{ inventory_hostname }}, IP {{ ansible_host }}"
- name: Print all variables
ansible.builtin.debug:
var: hostvars[inventory_hostname]
Check Mode (Dry Run)
# Show what would change without changing
ansible-playbook site.yml --check --diff
Step Mode
# Confirm each task before running
ansible-playbook site.yml --step
Start at Specific Task
ansible-playbook site.yml --start-at-task="Deploy application"
SSH Connection Errors
"UNREACHABLE! => SSH Error"
fatal: [web-01]: UNREACHABLE! => {"msg": "Failed to connect to the host via ssh"}
Fixes:
# Test SSH manually
ssh -vvv deploy@web-01
# Check host is reachable
ping web-01
# Check SSH key
ssh-add -l
# Specify key
ansible-playbook site.yml --private-key=~/.ssh/mykey
# Disable host key checking (dev only)
ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook site.yml
"Permission denied (publickey)"
# Copy SSH key to remote host
ssh-copy-id deploy@web-01
# Or specify password
ansible-playbook site.yml --ask-pass
# Check key permissions
chmod 600 ~/.ssh/id_rsa
chmod 700 ~/.ssh
Connection Timeout
# ansible.cfg — increase timeout
[defaults]
timeout = 30
[ssh_connection]
ssh_args = -C -o ConnectTimeout=30
Permission Errors
"MODULE FAILURE: Permission denied"
# WRONG — needs root
- name: Install package
ansible.builtin.apt:
name: nginx
# RIGHT — add become
- name: Install package
ansible.builtin.apt:
name: nginx
become: true
"sudo: a password is required"
# Provide sudo password
ansible-playbook site.yml --ask-become-pass
# Or configure passwordless sudo on remote host
echo "deploy ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/deploy
Variable Errors
"undefined variable"
fatal: [web-01]: FAILED! => {"msg": "'my_var' is undefined"}
Fixes:
# Use default filter
value: "{{ my_var | default('fallback') }}"
# Check if defined
- name: Task
...
when: my_var is defined
# Define in the right place
# group_vars/all.yml, host_vars/hostname.yml, or playbook vars
"dict object has no attribute"
# WRONG — attribute doesn't exist
msg: "{{ result.stdout }}"
# DEBUG — see what's actually in the variable
- debug: var=result
# RIGHT — use default
msg: "{{ result.stdout | default('') }}"
Module Errors
"No module named..."
# Install required collection
ansible-galaxy collection install community.general
# Check if module exists
ansible-doc -l | grep module_name
"Unsupported parameters"
fatal: [web-01]: FAILED! => {"msg": "Unsupported parameters for (apt) module: name_"}
Check for typos in parameter names:
# WRONG
- apt:
name_: nginx # Typo!
# RIGHT
- apt:
name: nginx
"Could not find or access"
# File not found — check paths
- copy:
src: myfile.conf # Relative to files/ or playbook dir
dest: /etc/myapp/
# Check: does files/myfile.conf exist?
# Or use absolute path:
src: /path/to/myfile.conf
YAML Syntax Errors
"could not find expected ':'"
# WRONG — colon in value without quotes
- debug:
msg: Error: something failed
# RIGHT — quote strings with colons
- debug:
msg: "Error: something failed"
"found character that cannot start any token"
# WRONG — tab indentation
- name: Task
ansible.builtin.debug: # TAB character!
# RIGHT — use spaces (2 or 4)
- name: Task
ansible.builtin.debug:
Indentation Errors
# WRONG
- name: Task
ansible.builtin.apt:
name: nginx # Wrong indent — looks like new task
# RIGHT
- name: Task
ansible.builtin.apt:
name: nginx # Indented under module
Slow Playbook Performance
# ansible.cfg — performance settings
[defaults]
forks = 20 # Parallel hosts (default: 5)
gathering = smart # Cache facts
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible-facts
[ssh_connection]
pipelining = True # Major speed boost
ssh_args = -C -o ControlMaster=auto -o ControlPersist=600s
# Skip fact gathering if not needed
- hosts: all
gather_facts: false
# Combine package installs
- apt:
name: [nginx, redis, git, curl]
state: present
Common Error Reference
| Error | Cause | Fix |
|---|---|---|
| UNREACHABLE | SSH can't connect | Check SSH, firewall, hostname |
| Permission denied | No sudo / wrong user | Add become: true, check SSH key |
| Undefined variable | Variable not set | Use default() filter, define in vars |
| No module named | Collection not installed | ansible-galaxy collection install |
| Unsupported parameters | Typo in parameter | Check ansible-doc module_name |
| could not find ':' | YAML syntax (unquoted colon) | Quote strings with special chars |
| Timeout | Slow network / command | Increase timeout, use async |
| Idempotency failure | Using command instead of module | Switch to proper module |
Useful Debug Commands
# Test connectivity
ansible all -m ping
# Run ad-hoc command
ansible web-01 -m command -a "uptime"
# List all hosts in inventory
ansible-inventory --list
# Show host variables
ansible-inventory --host web-01
# Check module documentation
ansible-doc apt
ansible-doc -s apt # Short snippet
# Syntax check (no execution)
ansible-playbook site.yml --syntax-check
# List tasks
ansible-playbook site.yml --list-tasks
# List hosts
ansible-playbook site.yml --list-hosts
Related Articles
- Ansible debug Module
- Ansible Error Handling
- Ansible cfg Guide
- Ansible Best Practices
- Common Ansible Errors
Conclusion
Most Ansible errors fall into 5 categories: SSH connection, permissions, undefined variables, module issues, and YAML syntax. Use -vvv for detailed output. Use debug to inspect variables. Use --check --diff to preview changes. The error message almost always tells you the exact problem — read it carefully. For persistent issues, check ansible-doc for the correct module parameters and ansible-inventory to verify your host configuration.