Introduction

Ansible playbook runs without loading host-specific variables from inventory. Variables defined in host_vars or inventory file are not available during playbook execution, causing tasks to fail or use wrong values.

Symptoms

Variable undefined:

```bash $ ansible-playbook site.yml -l server1

TASK [Configure app] *************** fatal: [server1]: FAILED! => { "msg": "The task includes an undefined variable 'app_port'." } ```

Wrong variable value:

```bash $ ansible server1 -m debug -a "var=app_port"

server1 | SUCCESS => { "app_port": 8080 # Expected 9000 from inventory } ```

Inventory not loaded:

```bash $ ansible-inventory --list

{ "_meta": { "hostvars": {} # Empty, host variables not found } } ```

Common Causes

  1. 1.Wrong inventory path - Ansible not finding inventory file
  2. 2.Invalid inventory format - YAML syntax errors
  3. 3.host_vars directory wrong - Not in correct location
  4. 4.Variable precedence override - Other sources overriding
  5. 5.Group vs host variables - Variables in wrong scope
  6. 6.Inventory file not parsed - Format not recognized

Step-by-Step Fix

Step 1: Check Inventory Path

```bash # Check current inventory path ansible-config dump | grep inventory

# Default locations: # - ansible.cfg: inventory = /path/to/inventory # - Environment: ANSIBLE_INVENTORY # - CLI: -i /path/to/inventory

# Check ansible.cfg grep inventory ansible.cfg

# Common settings: [defaults] inventory = ./inventory # Or: inventory = ./hosts.ini,./inventory/

# Test inventory loading ansible-inventory --list -i ./inventory

# Verify hosts found ansible all -i ./inventory --list-hosts

# Check if using correct inventory ansible-playbook site.yml -i ./inventory -v ```

Step 2: Verify Inventory File Format

```bash # Check inventory file exists ls -la inventory/ ls -la hosts.ini

# Validate YAML inventory syntax python -c "import yaml; yaml.safe_load(open('inventory.yaml'))"

# Or use ansible-inventory ansible-inventory -i inventory.yaml --list

# Valid YAML inventory format: --- all: hosts: server1: app_port: 9000 app_user: deploy server2: app_port: 8080 app_user: admin children: web: hosts: server1: server2: vars: nginx_port: 80

# INI format (hosts.ini): [web] server1 app_port=9000 app_user=deploy server2 app_port=8080 app_user=admin

[web:vars] nginx_port=80

# Validate INI format ansible-inventory -i hosts.ini --list ```

Step 3: Check host_vars Directory

```bash # host_vars should be adjacent to inventory file # Structure: # inventory/ # hosts.ini # group_vars/ # web.yml # host_vars/ # server1.yml # server2.yml

ls -la inventory/host_vars/ ls -la inventory/host_vars/server1.yml

# Check file content cat inventory/host_vars/server1.yml

--- app_port: 9000 app_user: deploy

# Verify ansible sees host_vars ansible-inventory --list -i inventory/hosts.ini

# Should show: { "_meta": { "hostvars": { "server1": { "app_port": 9000 } } } }

# If host_vars not adjacent to inventory, specify: ansible-playbook site.yml -i inventory/hosts.ini --extra-vars "@host_vars/server1.yml" ```

Step 4: Test Variable Loading

```bash # Debug variable value ansible server1 -m debug -a "var=app_port" -i inventory/

# Debug all host variables ansible server1 -m debug -a "var=hostvars[inventory_hostname]" -i inventory/

# Check inventory hierarchy ansible-inventory --graph -i inventory/

# Use verbose mode to see variable sources ansible-playbook site.yml -i inventory/ -vvv | grep app_port

# Show variable precedence ansible server1 -m debug -a "var=ansible_vars_sources" -i inventory/ ```

Step 5: Check Variable Precedence

```bash # Ansible variable precedence (lowest to highest): # 1. command line values (lowest) # 2. role defaults # 3. inventory file or script group vars # 4. inventory group_vars/all # 5. playbook group_vars/all # 6. inventory group_vars/* # 7. playbook group_vars/* # 8. inventory file or script host vars # 9. inventory host_vars/* # 10. playbook host_vars/* # 11. host facts / cached set_facts # 12. play vars # 13. play vars_prompt # 14. play vars_files # 15. role vars # 16. block vars # 17. task vars # 18. include_vars # 19. set_facts / registered vars # 20. role (and include_role) params # 21. include_params # 22. extra vars (highest)

# Check if variable being overridden ansible server1 -m debug -a "var=app_port" -vvv

# Check playbook variables grep app_port playbook.yml

# Check role defaults grep -r app_port roles/*/defaults/

# Check extra vars ansible-playbook site.yml -e "app_port=8080" # This overrides inventory host_vars! ```

Step 6: Fix Inventory Directory Structure

```bash # Correct structure for inventory directory:

mkdir -p inventory/group_vars inventory/host_vars

# Create inventory file cat << 'EOF' > inventory/hosts.ini [web] server1 server2

[db] server3 EOF

# Create host_vars cat << 'EOF' > inventory/host_vars/server1.yml --- app_port: 9000 app_user: deploy EOF

cat << 'EOF' > inventory/host_vars/server2.yml --- app_port: 8080 app_user: admin EOF

# Create group_vars cat << 'EOF' > inventory/group_vars/web.yml --- nginx_port: 80 nginx_user: www-data EOF

# Verify structure tree inventory/ # inventory/ # ├── hosts.ini # ├── group_vars/ # │ └── web.yml # └── host_vars/ # │ ├── server1.yml # │ └── server2.yml

# Test loading ansible-inventory -i inventory/hosts.ini --list ```

Step 7: Use Dynamic Inventory Correctly

```bash # For dynamic inventory plugins

# Check plugin configuration ansible-config dump | grep inventory_plugins

# Example AWS inventory plugin: # inventory/aws_ec2.yml plugin: aws_ec2 regions: - us-east-1 hostvars: app_port: 9000

# Verify plugin loaded ansible-inventory -i inventory/aws_ec2.yml --list

# For custom inventory scripts: ansible-inventory -i inventory/my_script.py --list

# Check script is executable chmod +x inventory/my_script.py

# Test script output python inventory/my_script.py # Should output valid JSON

# Multiple inventory sources: ansible-playbook site.yml -i inventory/hosts.ini -i inventory/aws_ec2.yml ```

Step 8: Verify Host Name Matching

```bash # host_vars file name must match host name exactly

# Check host names in inventory ansible-inventory --list -i inventory/hosts.ini | jq '.all.hosts'

# Host names: # server1, server2

# host_vars files must be: # inventory/host_vars/server1.yml # inventory/host_vars/server2.yml

# NOT: # inventory/host_vars/server1.local.yml # Wrong if host is 'server1' # inventory/host_vars/192.168.1.1.yml # Wrong if host is 'server1'

# Check if host_vars file matches host ls inventory/host_vars/

# If host name includes domain, include in filename: # Host: server1.example.com # File: inventory/host_vars/server1.example.com.yml

# Or use aliases in INI inventory: [web] server1 ansible_host=192.168.1.1 # host_vars/server1.yml will load ```

Step 9: Force Variable Reload

```bash # Clear ansible cache rm -rf ~/.ansible/cache/ rm -rf .ansible/

# Reload facts ansible server1 -m setup -i inventory/

# Use --flush-cache ansible-playbook site.yml -i inventory/ --flush-cache

# Force re-read inventory ansible-inventory -i inventory/hosts.ini --list --refresh

# Check ansible inventory manager ansible-config dump | grep inventory_cache

# Disable caching in ansible.cfg: [defaults] fact_caching = memory inventory_cache = false ```

Step 10: Debug Variable Sources

```bash # Create playbook to debug variable precedence cat << 'EOF' > debug_vars.yml --- - hosts: all tasks: - name: Debug app_port value debug: var: app_port

  • name: Debug all host vars
  • debug:
  • var: hostvars[inventory_hostname]
  • name: Debug inventory hostname
  • debug:
  • var: inventory_hostname
  • name: Debug group names
  • debug:
  • var: group_names
  • name: Show variable source
  • shell: echo "app_port from host_vars"
  • when: app_port == 9000
  • EOF

ansible-playbook debug_vars.yml -i inventory/ -vv

# Use ansible-doc for inventory plugin help ansible-doc -t inventory aws_ec2 ansible-doc -t inventory yaml ```

Ansible Inventory Variables Checklist

CheckCommandExpected
Inventory pathansible-config dumpCorrect path
Host vars filels host_vars/Matches host name
Variable valuedebug var=Expected value
Inventory graph--graphShows host_vars
YAML syntaxpython yaml.loadNo errors
Precedencedebug -vvvNo override

Verification

```bash # After fixing inventory variable loading

# 1. Verify host_vars loaded ansible-inventory --list -i inventory/ | jq '.["_meta"]["hostvars"]["server1"]' // Should show host variables

# 2. Check variable value ansible server1 -m debug -a "var=app_port" -i inventory/ // Should show expected value (9000)

# 3. Run playbook successfully ansible-playbook site.yml -i inventory/ -l server1 // Tasks should use correct variable values

# 4. Verify no override ansible-playbook site.yml -vvv | grep app_port // Should show value from host_vars

# 5. Check inventory graph ansible-inventory --graph -i inventory/ // Shows host variables attached to hosts

# 6. Test with multiple hosts ansible all -m debug -a "var=app_port" -i inventory/ // Each host shows its own port ```

Prevention

To prevent Ansible inventory host variables not loading issues from recurring, implement these proactive measures:

1. Validate Inventory Structure

```bash # Add pre-run inventory validation ansible-inventory -i inventory/ --list --check

# Create validation script cat << 'EOF' > validate_inventory.sh #!/bin/bash # Check host_vars directory structure for host in $(ansible-inventory -i inventory/ --list | jq -r '.[] | keys[]'); do if [ ! -f "inventory/host_vars/${host}.yml" ]; then echo "WARNING: Missing host_vars for $host" fi done EOF chmod +x validate_inventory.sh ```

2. Monitor Variable Loading

yaml
groups:
- name: ansible-validation
  rules:
  - alert: AnsibleInventoryMissingVars
    expr: |
      ansible_inventory_validation_errors > 0
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: "Ansible inventory has missing or invalid variables"

Best Practices Checklist

  • [ ] Use consistent host naming in inventory
  • [ ] Validate inventory before playbook runs
  • [ ] Document variable precedence rules
  • [ ] Use ansible-inventory --graph for visualization
  • [ ] Disable caching for dynamic inventory
  • [ ] Test with ansible-inventory --list
  • [Fix Ansible Variable Undefined](/articles/fix-ansible-variable-undefined)
  • [Fix Ansible Inventory Not Found](/articles/fix-ansible-inventory-not-found)
  • [Fix Ansible Group Variables Not Applied](/articles/fix-ansible-group-variables-not-applied)
  • [WordPress troubleshooting: Ansible Artifact Download Uses an Old Mi](ansible-artifact-download-uses-an-old-mirror-after-proxy-change)
  • [WordPress troubleshooting: Ansible Audit Trail Misses Events Under ](ansible-audit-trail-misses-events-under-burst-load)
  • [WordPress troubleshooting: Ansible Background Worker Gets Stuck in ](ansible-background-worker-stuck-in-a-retry-loop)
  • [WordPress troubleshooting: Ansible Backup Completes but Restore Fai](ansible-backup-completes-but-restore-fails-checksum-validation)
  • [WordPress troubleshooting: Ansible Batch Importer Duplicates Rows A](ansible-batch-importer-duplicates-rows-after-a-retry)

<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix Ansible Inventory Host Variables Not Loading", "description": "Troubleshoot Ansible inventory host variables not loading. Check format, precedence, file structure.", "url": "https://www.fixwikihub.com/fix-ansible-inventory-host-variables-not-loading", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-04T21:45:15.635Z", "dateModified": "2026-04-04T21:45:15.635Z" } </script>