Your playbook runs but targets the wrong hosts, or worse, Ansible can't parse your inventory at all. Inventory errors are fundamental - without a correct inventory, Ansible doesn't know what to manage. Let's fix these systematically.
Understanding the Error
Inventory errors come in several forms:
[WARNING]: Unable to parse /path/to/inventory as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is availableOr:
ERROR! the file 'inventory' does not exist or cannot be readOr subtler issues where hosts aren't in the groups you expect.
Step 1: Verify Inventory File Exists and Is Readable
Start with the basics:
```bash # Check file exists ls -la inventory/
# Verify it's readable cat inventory/hosts ```
Check what Ansible sees:
```bash # List all inventory sources ansible-config dump | grep INVENTORY
# Show effective inventory paths ansible-inventory -i inventory --list ```
If Ansible can't find your inventory, specify it explicitly:
ansible-playbook -i inventory/hosts site.ymlOr set the default in ansible.cfg:
[defaults]
inventory = ./inventory/hostsStep 2: Validate INI Format
INI format is common but easy to break. Here's a valid example:
```ini [webservers] webserver01 ansible_host=192.168.1.10 webserver02 ansible_host=192.168.1.11
[webservers:vars] http_port=80
[dbservers] dbserver01 ansible_host=192.168.1.20
[production:children] webservers dbservers ```
Common INI format errors:
Trailing spaces after values: ```ini # WRONG - space after the IP webserver01 ansible_host=192.168.1.10
# CORRECT webserver01 ansible_host=192.168.1.10 ```
Wrong group hierarchy syntax: ```ini # WRONG [production] [production:children] webservers
# CORRECT [production:children] webservers ```
Missing section headers: ```ini # WRONG - no section header webserver01 ansible_host=192.168.1.10
# CORRECT [webservers] webserver01 ansible_host=192.168.1.10 ```
Validate your inventory:
ansible-inventory -i inventory/hosts --listIf this fails, your inventory has syntax errors.
Step 3: Validate YAML Format
YAML inventory is powerful but whitespace-sensitive:
all:
children:
webservers:
hosts:
webserver01:
ansible_host: 192.168.1.10
webserver02:
ansible_host: 192.168.1.11
vars:
http_port: 80
dbservers:
hosts:
dbserver01:
ansible_host: 192.168.1.20
production:
children:
webservers:
dbservers:Common YAML inventory errors:
Inconsistent indentation: ```yaml # WRONG all: children: webservers: hosts: webserver01:
# CORRECT (2 spaces consistently) all: children: webservers: hosts: webserver01: ```
Missing colons: ```yaml # WRONG all: children webservers
# CORRECT all: children: webservers: ```
Validate YAML syntax:
```bash # Check YAML syntax python3 -c "import yaml; yaml.safe_load(open('inventory/hosts.yml'))"
# Or use Ansible ansible-inventory -i inventory/hosts.yml --list ```
Step 4: Check Host Resolution
Hosts in inventory must resolve:
```bash # Test host resolution ansible all -i inventory -m ping
# Check specific host ansible webserver01 -i inventory -m debug -a "var=ansible_host" ```
If hosts show as unreachable, verify DNS or /etc/hosts:
```bash # Check what Ansible sees ansible-inventory -i inventory --host webserver01
# Verify resolution ping webserver01 ```
Use IP addresses if DNS is unreliable:
[webservers]
webserver01 ansible_host=192.168.1.10Step 5: Verify Group Membership
Hosts not in expected groups is a common issue:
```bash # List all groups ansible-inventory -i inventory --graph
# List hosts in a group ansible webservers -i inventory --list-hosts
# Show groups for a host ansible-inventory -i inventory --host webserver01 ```
Common group issues:
Wrong group names (case-sensitive):
``ini
[WebServers] # This won't match "webservers"
webserver01
Children syntax errors: ```ini # WRONG [production] children: webservers
# CORRECT [production:children] webservers ```
Not applying vars to groups: ```ini # WRONG - vars defined after hosts [webservers] webserver01
[webservers:vars] http_port=80 # Applied correctly
[dbservers] dbserver01
# WRONG - forgot :vars [dbservers:vars] db_port=5432 ```
Step 6: Handle Dynamic Inventory
Dynamic inventory scripts must be executable and return valid JSON:
```bash # Test dynamic inventory script ./inventory/ec2.py --list
# Verify JSON output ./inventory/ec2.py --list | python3 -m json.tool ```
For dynamic inventory, ensure:
```bash # Script is executable chmod +x inventory/ec2.py
# Correct shebang head -1 inventory/ec2.py # Should show: #!/usr/bin/env python3 ```
Common dynamic inventory errors:
Missing cache refresh:
``bash
# Force refresh
ansible-inventory -i inventory/ec2.py --refresh-cache --list
AWS credentials not set: ```bash # Check credentials aws sts get-caller-identity
# Or set environment variables export AWS_ACCESS_KEY_ID=xxx export AWS_SECRET_ACCESS_KEY=xxx ```
Step 7: Test Inventory Variables
Verify variables are applied correctly:
```bash # Show all variables for a host ansible-inventory -i inventory --host webserver01
# Check specific variable ansible webserver01 -i inventory -m debug -a "var=http_port" ```
Variable precedence can confuse things:
# Check which value wins
ansible webserver01 -i inventory -m debug -a "var=ansible_host"- 1.Variables defined in multiple places have precedence order:
- 2.Extra vars (
-e) - highest - 3.Task vars
- 4.Play vars
- 5.Host facts
- 6.Inventory host_vars
- 7.Inventory group_vars
- 8.Role defaults - lowest
Step 8: Debug Inventory Loading
Enable inventory debugging:
# Show inventory loading details
ANSIBLE_DEBUG=True ansible-inventory -i inventory --list 2>&1 | grep -i inventoryOr use verbose mode:
ansible-inventory -i inventory --list -vvvStep 9: Fix Common Specific Errors
Error: "No hosts matched"
```bash # Verify group exists ansible-inventory -i inventory --graph
# Check for typos ansible-inventory -i inventory --list | grep -i webserver ```
Error: "Invalid inventory source"
```bash # Check file format file inventory/hosts
# Try each format explicitly ansible-inventory -i inventory/hosts --list # INI ansible-inventory -i inventory/hosts.yml --list # YAML ```
Error: "Permission denied"
# Fix permissions
chmod 644 inventory/hostsStep 10: Verify Inventory Directory Structure
For complex inventories with group_vars and host_vars:
inventory/
├── hosts
├── group_vars/
│ ├── all.yml
│ ├── webservers.yml
│ └── production.yml
└── host_vars/
├── webserver01.yml
└── webserver02.ymlVerify structure:
```bash # Check directory layout tree inventory/
# Verify variables load ansible webserver01 -i inventory -m debug -a "var=host_specific_var" ```
Quick Verification
Test your inventory comprehensively:
```bash # List all hosts ansible all -i inventory --list-hosts
# Show inventory graph ansible-inventory -i inventory --graph
# Verify host connectivity ansible all -i inventory -m ping
# Check group variables ansible webservers -i inventory -m debug -a "var=http_port" ```
Expected output shows all hosts, correct groups, and applied variables:
hosts (3):
webserver01
webserver02
dbserver01Prevention Best Practices
- 1.Use inventory validation in CI:
# Add to CI pipeline
ansible-inventory -i inventory --list > /dev/null- 1.Document inventory structure:
# inventory/README.md
# Inventory Structure
# - hosts: Main inventory file
# - group_vars/: Group-specific variables
# - host_vars/: Host-specific variables- 1.Use consistent naming:
```ini # Good naming convention [web_prod] web-prod-01 web-prod-02
[web_staging] web-staging-01
[web:children] web_prod web_staging ```
Inventory errors are usually syntax issues or misconfiguration. Use ansible-inventory to validate and inspect, and always test with --list-hosts before running playbooks against targets.