You run ansible-playbook site.yml and instead of executing your playbook, Ansible throws an error like ERROR! Unable to parse inventory or Invalid inventory script. Inventory parsing failures prevent Ansible from knowing which hosts to manage, bringing your automation to a complete stop.
Understanding Inventory Parsing
Ansible inventory defines your infrastructure - hosts, groups, and variables. Inventory can be static (INI or YAML files) or dynamic (scripts that query cloud APIs). Parsing errors occur when Ansible cannot interpret the inventory format, whether due to syntax errors, permission issues, or script failures.
Diagnosis Commands
Check inventory parsing directly:
```bash # List all hosts (tests inventory parsing) ansible all --list-hosts -i inventory
# Show inventory graph ansible-inventory -i inventory --graph
# List inventory in YAML format ansible-inventory -i inventory --list
# Verify specific inventory file ansible-inventory -i inventory.yml --verify ```
Check for syntax errors:
```bash # For YAML inventory yamllint inventory.yml
# For INI inventory ansible-inventory -i inventory.ini --list ```
For dynamic inventory scripts:
```bash # Test dynamic inventory script directly ./inventory/ec2.py --list
# Check script permissions ls -la inventory/ec2.py
# Verify script is executable chmod +x inventory/ec2.py ```
Common Solutions
Solution 1: Fix INI Inventory Format Issues
Correct INI inventory structure:
```ini # WRONG: Invalid group name with spaces [Web Servers] web1.example.com web2.example.com
# CORRECT: Valid group name (no spaces, underscores) [web_servers] web1.example.com web2.example.com ```
Variables in INI format:
```ini # WRONG: Invalid variable syntax [web_servers] web1 ansible_user=admin ansible_port=2222 invalid_var
# CORRECT: Proper key=value format [web_servers] web1 ansible_user=admin ansible_port=2222
# Group variables section [web_servers:vars] ansible_user=admin ansible_python_interpreter=/usr/bin/python3 ```
Nested groups:
```ini # Parent group with children [production:children] web_servers db_servers
[web_servers] web1.example.com web2.example.com
[db_servers] db1.example.com ```
Solution 2: Fix YAML Inventory Format Issues
Correct YAML inventory structure:
```yaml # WRONG: Invalid structure all: hosts: web1.example.com web2.example.com
# CORRECT: Proper structure all: hosts: web1.example.com: web2.example.com: children: web_servers: hosts: web1.example.com: web2.example.com: ```
Host variables in YAML:
# CORRECT: Host variables
all:
children:
web_servers:
hosts:
web1.example.com:
ansible_user: admin
ansible_port: 2222
app_port: 8080
vars:
ansible_python_interpreter: /usr/bin/python3Solution 3: Fix Dynamic Inventory Script Errors
For executable inventory scripts:
```bash # Make script executable chmod +x inventory/dynamic.sh
# Test script output directly ./inventory/dynamic.sh --list | python3 -m json.tool
# Verify JSON output is valid ./inventory/dynamic.sh --list > /tmp/inventory.json python3 -c "import json; json.load(open('/tmp/inventory.json'))" ```
Common dynamic inventory script fixes:
```bash # AWS EC2 inventory # Install required Python packages pip install boto3
# Configure AWS credentials aws configure
# Test EC2 inventory ./contrib/inventory/ec2.py --list
# Azure inventory pip install msrestazure azure.common
# GCP inventory pip install google-auth requests ```
Solution 4: Fix Inventory Plugin Configuration
For inventory plugins (AWS, Azure, etc.):
# aws_ec2.yml inventory plugin configuration
plugin: aws_ec2
regions:
- us-east-1
- us-west-2
filters:
tag:Environment: production
compose:
ansible_host: private_ip_addressEnable required plugins:
# ansible.cfg
[inventory]
enable_plugins = aws_ec2, azure_rm, gcp_compute, host_list, script, autoTest inventory plugin:
```bash # Use with inventory plugin ansible-inventory -i aws_ec2.yml --graph
# List hosts ansible all -i aws_ec2.yml --list-hosts ```
Solution 5: Fix Group Variable Conflicts
Conflicting variable definitions:
```yaml # Check for conflicts in group_vars grep -r "variable_name" group_vars/
# ansible-inventory shows merged variables ansible-inventory -i inventory --host web1.example.com ```
Variable precedence issues:
```yaml # Inventory file variables (lowest precedence) [web_servers:vars] app_port=8080
# group_vars/web_servers.yml (higher precedence) app_port: 9090
# host_vars/web1.example.com.yml (highest precedence) app_port: 3000 ```
Debug variable sources:
```bash # Show all variables for a host ansible web1.example.com -m debug -a "var=hostvars[inventory_hostname]"
# Show specific variable source ansible web1.example.com -m debug -a "var=app_port" ```
Solution 6: Fix File Encoding Issues
Inventory files must be UTF-8 encoded:
```bash # Check file encoding file inventory.yml
# Convert to UTF-8 if needed iconv -f ISO-8859-1 -t UTF-8 inventory.yml > inventory_fixed.yml
# Remove BOM if present sed -i '1s/^\xEF\xBB\xBF//' inventory.yml ```
Solution 7: Fix Special Characters in Hostnames
Hostnames with special characters need quotes:
```yaml # WRONG: Special characters unquoted all: hosts: web-server-01.example.com: # Hyphens are OK web_server_01.example.com: # Underscores are OK web[01].example.com: # Brackets need escaping
# CORRECT: Proper quoting all: hosts: "web[01].example.com": "web-server-01.example.com": ```
Verification
After fixing inventory issues:
```bash # Verify inventory parses correctly ansible-inventory -i inventory --graph
# List all hosts ansible all -i inventory --list-hosts
# Test connectivity ansible all -i inventory -m ping
# Run playbook with specific inventory ansible-playbook site.yml -i inventory ```
Common Error Messages
| Error | Cause | Fix |
|---|---|---|
No such file or directory | Missing inventory file | Create file or check path |
Permission denied | Script not executable | chmod +x script.sh |
Invalid inventory script | Script doesn't output valid JSON | Debug script output |
Unable to parse | Syntax error in inventory | Check YAML/INI syntax |
group_vars not found | Missing directory | Create group_vars/ directory |
Multiple Inventory Sources
Combine multiple inventory sources:
```bash # Directory-based inventory ansible-playbook site.yml -i inventory/
# Multiple files ansible-playbook site.yml -i inventory.ini -i inventory.yml
# Mix static and dynamic ansible-playbook site.yml -i inventory/ -i ec2_inventory.py ```
Directory structure for multiple inventories:
inventory/
├── group_vars/
│ ├── all.yml
│ └── web_servers.yml
├── host_vars/
│ └── web1.example.com.yml
├── production.ini
└── staging.iniInventory parsing errors usually stem from simple syntax mistakes or configuration issues. Start with ansible-inventory --list to see what Ansible is reading, then work through the format corrections based on the error message.