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:

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/python3

Solution 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.):

yaml
# 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_address

Enable required plugins:

ini
# ansible.cfg
[inventory]
enable_plugins = aws_ec2, azure_rm, gcp_compute, host_list, script, auto

Test 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

ErrorCauseFix
No such file or directoryMissing inventory fileCreate file or check path
Permission deniedScript not executablechmod +x script.sh
Invalid inventory scriptScript doesn't output valid JSONDebug script output
Unable to parseSyntax error in inventoryCheck YAML/INI syntax
group_vars not foundMissing directoryCreate 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:

bash
inventory/
├── group_vars/
│   ├── all.yml
│   └── web_servers.yml
├── host_vars/
│   └── web1.example.com.yml
├── production.ini
└── staging.ini

Inventory 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.