Introduction

YAML syntax errors are among the most common Ansible failures. When a playbook contains malformed YAML, Ansible cannot parse it and fails immediately before any task executes. These errors stem from YAML's strict indentation rules, special character handling, quoting requirements, and the interaction between YAML syntax and Jinja2 templating.

The error messages can be cryptic, often pointing to the wrong line number due to how YAML parsers work. Understanding common YAML pitfalls and using proper validation tools helps quickly identify and fix these issues.

Symptoms

Basic YAML syntax errors:

```bash $ ansible-playbook site.yml ERROR! Syntax Error while loading YAML. did not find expected '-' indicator

The error appears to be in 'site.yml': line 15, column 5, but may be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

tasks: - name: Install nginx ^ here ```

Indentation errors:

```bash $ ansible-playbook deploy.yml ERROR! Syntax Error while loading YAML. mapping values are not allowed in this context

The error appears to be in 'deploy.yml': line 23, column 12

The offending line appears to be:

  • name: Configure app
  • template:
  • src: app.conf.j2
  • dest: /etc/app/app.conf
  • ^ here
  • `

Jinja2 template quoting issues:

```bash $ ansible-playbook config.yml ERROR! Syntax Error while loading YAML. found unexpected end of stream

The error appears to be in 'config.yml': line 45

The offending line appears to be:

  • debug: msg={{ ansible_hostname }}
  • ^ here
  • `

Missing colon errors:

```bash $ ansible-playbook site.yml ERROR! Syntax Error while loading YAML. could not find expected ':'

The offending line appears to be:

  • name Start service
  • ^ here
  • `

Complex Jinja2 expression issues:

```bash $ ansible-playbook complex.yml ERROR! Syntax Error while loading YAML. template error while templating string: unexpected char '$' at 15

The offending line appears to be:

value: "{{ $var }}" ^ here ```

Common Causes

1. Tab Characters Mixed with Spaces

YAML forbids tab characters for indentation:

yaml
# WRONG - contains tabs
- name: Install package
  yum:
	name: nginx  # This line uses a tab!
	state: present

2. Inconsistent Indentation

YAML requires consistent indentation levels:

yaml
# WRONG - inconsistent indentation
- name: Deploy app
  tasks:
    - name: Copy files
      copy:
        src: app/
       dest: /opt/app/  # One space less than previous line

3. Unquoted Special Characters

Colons, hashes, and other special characters need quoting:

```yaml # WRONG - unquoted value with colon - set_fact: message: This is a test: value

# CORRECT - set_fact: message: "This is a test: value" ```

4. Improper Jinja2 Syntax

Jinja2 expressions must be properly enclosed:

```yaml # WRONG - missing closing braces - debug: msg: "{{ item.name "

# WRONG - nested braces incorrectly - debug: msg: "{{ {{ item.name }} }}" ```

5. List vs Dict Confusion

Mixing list and dict syntax:

yaml
# WRONG - dict item in list
tasks:
  - name: Task one
    command: echo "one"
  name: Task two  # Missing dash!
    command: echo "two"

6. Multiline String Issues

Incorrect multiline string format:

yaml
# WRONG - literal block scalar with wrong indicator
- shell: |
    echo "line one"
   echo "line two"  # Wrong indentation for block

Step-by-Step Fix

Step 1: Run Syntax Check

Validate playbook syntax:

```bash # Basic syntax check ansible-playbook --syntax-check playbook.yml

# With more detail ansible-playbook --syntax-check playbook.yml -vv

# Use yamllint for detailed YAML validation pip install yamllint yamllint playbook.yml

# Check all playbooks in directory yamllint roles/*.yml playbooks/*.yml ```

Step 2: Check for Tab Characters

Find and fix tab characters:

```bash # Find tabs in playbook grep -P '\t' playbook.yml

# Or with cat -A (shows tabs as ^I) cat -A playbook.yml | grep '\^I'

# Replace tabs with spaces sed -i 's/\t/ /g' playbook.yml

# In Vim, convert tabs to spaces :set expandtab :retab ```

Step 3: Fix Indentation Issues

Use proper indentation (2 spaces is Ansible convention):

yaml
# Correct indentation pattern
---
- name: Play name
  hosts: all
  vars:
    var1: value1
    var2: value2
  tasks:
    - name: Task name
      module_name:
        parameter1: value1
        parameter2: value2
      notify:
        - handler_name
  handlers:
    - name: handler_name
      module_name:
        parameter: value

Configure editor for YAML indentation:

```yaml # .editorconfig root = true

[*.yml] indent_style = space indent_size = 2

[*.yaml] indent_style = space indent_size = 2 ```

Step 4: Fix Jinja2 Template Quoting

Properly quote Jinja2 expressions:

```yaml # WRONG - unquoted Jinja2 - debug: msg={{ item }} when: item == true

# CORRECT - quoted Jinja2 - debug: msg: "{{ item }}" when: item == true

# WRONG - special characters - set_fact: url: http://{{ host }}:{{ port }}/api

# CORRECT - quote the entire value - set_fact: url: "http://{{ host }}:{{ port }}/api"

# WRONG - colon in string - set_fact: message: Status: OK

# CORRECT - set_fact: message: "Status: OK" ```

Step 5: Fix Multiline Strings

Use correct multiline string formats:

```yaml # Literal block scalar (preserves newlines) - shell: | echo "line one" echo "line two" echo "line three"

# Folded block scalar (newlines become spaces) - debug: msg: > This is a very long message that will be folded into a single line when parsed.

# Literal with strip (removes trailing newline) - shell: |- echo "no trailing newline"

# Literal with keep (preserves trailing newlines) - shell: |+ echo "preserves trailing newlines" ```

Step 6: Fix List and Dict Syntax

Use correct collection syntax:

```yaml # List of tasks tasks: - name: First task command: echo "first" - name: Second task command: echo "second"

# List of values vars: my_list: - item1 - item2 - item3

# Dictionary vars: my_dict: key1: value1 key2: value2

# List of dictionaries vars: my_list_of_dicts: - name: item1 value: 100 - name: item2 value: 200 ```

Step 7: Use ansible-lint for Comprehensive Checks

Install and run ansible-lint:

```bash # Install ansible-lint pip install ansible-lint

# Run lint ansible-lint playbook.yml

# With specific rules ansible-lint --exclude=106 playbook.yml

# Show rule documentation ansible-lint -L

# Fix automatically where possible ansible-lint --fix playbook.yml ```

Create ansible-lint configuration:

```yaml # .ansible-lint exclude_paths: - .github/ - tests/

skip_list: - yaml[colons] # Skip specific rule

enable_list: - name[play] # Enable additional rules

rulesdir: - ./custom_rules/ ```

Step 8: Debug Complex Syntax Issues

Isolate the problematic section:

yaml
# Create minimal test playbook
---
- name: Test playbook
  hosts: localhost
  gather_facts: false
  tasks:
    # Paste problematic section here
    - debug:
        msg: "test"

Use Python YAML parser directly:

```python #!/usr/bin/env python3 import yaml import sys

with open(sys.argv[1], 'r') as f: try: data = yaml.safe_load(f) print("YAML is valid") print(yaml.dump(data, default_flow_style=False)) except yaml.YAMLError as e: print(f"YAML error: {e}") ```

Verification

After fixing syntax errors:

```bash # Run syntax check ansible-playbook --syntax-check playbook.yml # Should show: playbook.yml: OK

# Run yamllint yamllint playbook.yml # Should show no errors

# Run ansible-lint ansible-lint playbook.yml # Should show no errors (or only warnings)

# Try running the playbook ansible-playbook playbook.yml --check # Should execute without syntax errors

# Verify specific tasks ansible-playbook playbook.yml --list-tasks # Should list all tasks correctly ```

Test in isolated environment:

```bash # Create test directory mkdir -p /tmp/ansible-test cp playbook.yml /tmp/ansible-test/

# Run syntax check in isolation cd /tmp/ansible-test ansible-playbook --syntax-check playbook.yml ```

  • [ansible-playbook-undefined-variable-jinja2-strict-mode](/articles/ansible-playbook-undefined-variable-jinja2-strict-mode)
  • [ansible-jinja2-template-errors](/articles/ansible-jinja2-template-errors)
  • [ansible-yaml-best-practices](/articles/ansible-yaml-best-practices)
  • [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": "WordPress troubleshooting: Ansible Playbook Syntax Error - YAML Par", "description": "Learn how to fix Ansible Playbook Syntax Error - YAML Parsing Failed. Professional WordPress troubleshooting solutions with step-by-step guidance. WP error fix, WordPress optimization, WP security, WordPress performance.", "url": "https://www.fixwikihub.com/ansible-playbook-syntax-yaml-error", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2025-12-15T19:14:01.783Z", "dateModified": "2025-12-15T19:14:01.783Z" } </script>