Ansible Syntax Error: Debug & Fix YAML Playbook Errors (Guide)
By Luca Berton · Published 2024-01-01 · Category: installation
Fix Ansible syntax errors in playbooks. Debug YAML indentation, quoting, colons, and common YAML gotchas with step-by-step troubleshooting examples.

Introduction
Today we're going to talk about Ansible troubleshooting and specifically about Syntax Errors. I'm Luca Berton, and welcome to today's episode of Ansible Pilot.
See also: Ansible troubleshooting — Invalid plugin name: regex.replace Error in Ansible
Demo
The best way of talking about Ansible troubleshooting is to jump into a live Playbook to show you practically the syntax error and how to solve it!
Error Code
report.txt:
test report.txt
syntax_error.yml:
---
- name: win_copy module Playbook
hosts: all
become: false
gather_facts: false
vars:
source: "report.txt"
destination: "Desktop/report.txt"
tasks:
- name: copy report.txt
ansible.windows.win_copy:
src: "{{ source }}"
dest: "{{ destination }}
See also: Ansible 'chgrp failed' Error: Fix Group Ownership Permission Issues
Error Execution
Output:
$ ansible-playbook -i win/inventory troubleshooting/syntax_error.yml
ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: Expecting value: line 1 column 1 (char 0)
Syntax Error while loading YAML.
found unexpected end of stream
The error appears to be in 'ansible-pilot/troubleshooting/syntax_error.yml': line 14, column 1, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
src: "{{ source }}"
dest: "{{ destination }}
^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:
with_items:
- {{ foo }}
Should be written as:
with_items:
- "{{ foo }}"
Fix Code
syntax_fix.yml:
---
- name: win_copy module Playbook
hosts: all
become: false
gather_facts: false
vars:
source: "report.txt"
destination: "Desktop/report.txt"
tasks:
- name: copy report.txt
ansible.windows.win_copy:
src: "{{ source }}"
dest: "{{ destination }}"
See also: Ansible troubleshooting - AWS Failed to import the required Python library (botocore or boto3)
Fix Execution
Output:
$ ansible-playbook -i win/inventory troubleshooting/syntax_fix.yml
PLAY [win_copy module Playbook] ***********************************************************************
TASK [copy report.txt] ****************************************************************************
ok: [WindowsServer]
PLAY RECAP ****************************************************************************************
WindowsServer : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Conclusion
Now you know better how to troubleshoot the Ansible Syntax Error.
Common Syntax Errors and Fixes
Error 1: "could not find expected ':'"
ERROR! Syntax Error while loading YAML.
could not find expected ':'
Cause: Missing colon after a key, or unquoted string containing a colon.
# ❌ WRONG
- name: Deploy app
hosts: all
tasks
- name: test
debug:
msg: "hello"
# ✅ FIX — add colon after tasks
- name: Deploy app
hosts: all
tasks:
- name: test
debug:
msg: "hello"
Error 2: "mapping values are not allowed here"
ERROR! mapping values are not allowed in this context
Cause: Usually a colon inside an unquoted string.
# ❌ WRONG
- name: Show message
debug:
msg: Error: something failed
# ✅ FIX — quote the string
- name: Show message
debug:
msg: "Error: something failed"
Error 3: "did not find expected key"
Cause: Inconsistent indentation within a block.
# ❌ WRONG — mixed indentation
- name: Install packages
apt:
name: curl
state: present # Extra space!
# ✅ FIX
- name: Install packages
apt:
name: curl
state: present
Error 4: "We were unable to read either as JSON nor YAML"
Cause: Jinja2 variable used without quotes.
# ❌ WRONG
- name: Set variable
set_fact:
my_dict: {key: {{ value }}}
# ✅ FIX — quote the entire value
- name: Set variable
set_fact:
my_dict: "{key: {{ value }}}"
Debugging Tools
1. --syntax-check (built-in)
ansible-playbook playbook.yml --syntax-check
Catches basic YAML and Ansible syntax errors without executing the playbook.
2. yamllint (detailed YAML validation)
pip install yamllint
yamllint playbook.yml
Catches indentation issues, trailing spaces, line length, and more.
3. ansible-lint (best practices + syntax)
pip install ansible-lint
ansible-lint playbook.yml
Goes beyond syntax — checks for deprecated modules, missing name fields, risky practices.
4. VS Code YAML extension
Install "YAML" by Red Hat — provides real-time syntax highlighting and error detection:
// settings.json
{
"yaml.schemas": {
"https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/ansible.json#/$defs/playbook": "*.yml"
}
}
Prevention Best Practices
Always quote strings with special chars::, {, }, [, ], #, &, *, !, |, >, ', ", %, @
Use --syntax-check before every run
Set up pre-commit hooks with yamllint
Use 2-space indentation consistently
Never use tabs in YAML files
FAQ
How do I find the exact line with the error?
Ansible usually shows the file and line number. But the actual error is often above the reported line. Look at the preceding 5-10 lines.
Why does my playbook work locally but fail on the server?
Different Ansible versions parse YAML slightly differently. Also check for invisible characters (BOM, Windows line endings):
# Check for Windows line endings
file playbook.yml
# Convert if needed
dos2unix playbook.yml
How do I validate all playbooks in a project?
find . -name "*.yml" -exec ansible-playbook {} --syntax-check \;
# Or better
ansible-lint .
Check Syntax
ansible-playbook site.yml --syntax-check
# Or
ansible-lint site.yml
Common Syntax Errors
Wrong Indentation
# WRONG — tasks not properly indented
- hosts: all
tasks:
- debug: msg="hello"
# CORRECT
- hosts: all
tasks:
- debug: msg="hello"
Unquoted Colons
# WRONG — YAML interprets colon as key:value
- debug:
msg: Error: file not found
# CORRECT — quote strings with colons
- debug:
msg: "Error: file not found"
Unquoted Special Characters
# WRONG — YAML special characters
- debug: msg={{ variable }} # Needs quotes
- debug: msg=* is important # Asterisk
- debug: msg=yes # Boolean!
# CORRECT
- debug: msg="{{ variable }}"
- debug: msg="* is important"
- debug: msg="yes" # String, not boolean
Boolean Gotcha
# YAML treats these as booleans:
# yes/no, true/false, on/off
# WRONG — becomes boolean True
country: no # Norway? Nope, becomes False!
# CORRECT
country: "no" # String "no"
Missing Module Colon
# WRONG — missing colon after module
- debug
msg: "hello"
# CORRECT
- debug:
msg: "hello"
Tab Characters
# WRONG — YAML forbids tabs
- hosts: all
→ tasks: # Tab character!
→ → - debug: msg="hello"
# CORRECT — use spaces only
- hosts: all
tasks:
- debug: msg="hello"
Debugging Steps
# Step 1: Syntax check
ansible-playbook site.yml --syntax-check
# Step 2: Validate YAML
python3 -c "import yaml; yaml.safe_load(open('site.yml'))"
# Step 3: Use yamllint
pip install yamllint
yamllint site.yml
# Step 4: Check specific line
sed -n '42p' site.yml # Show line 42
Complex Value Quoting
# WRONG — Jinja2 needs quotes in YAML
- debug: msg={{ var }}
# CORRECT options
- debug: msg="{{ var }}"
- debug:
msg: "{{ var }}"
# Multi-line with variables
- debug:
msg: >
Server {{ hostname }} is running
on port {{ port }}
Multi-Line Strings
# Literal block (preserves newlines)
content: |
line 1
line 2
line 3
# Folded block (joins lines)
content: >
this is all
one long
line
# Literal, strip trailing newline
content: |-
no trailing
newline
Common Error Messages
| Error | Likely Cause |
|-------|-------------|
| could not find expected ':' | Missing colon or bad indentation |
| mapping values are not allowed | Unquoted colon in value |
| found character that cannot start | Tab character or special char |
| did not find expected key | Indentation mismatch |
| found unexpected end of stream | Unclosed quote or bracket |
| duplicate key | Same key twice in a mapping |
IDE Setup
Use an editor with YAML support:
• VS Code + Ansible extension — real-time syntax validation
• vim — set expandtab shiftwidth=2
• PyCharm — YAML/Ansible plugin
// VS Code settings.json
{
"editor.tabSize": 2,
"editor.insertSpaces": true,
"files.associations": {
"*.yml": "ansible"
}
}
FAQ
How do I find tab characters?
grep -P '\t' playbook.yml
cat -A playbook.yml | grep '\^I' # Shows tabs as ^I
Why does when: var == "yes" fail?
YAML may parse yes as boolean before Ansible sees it. Quote the value: when: var == "yes" (the quotes are part of the Jinja2 expression here, which is fine).
Syntax check passes but playbook fails?
--syntax-check only validates YAML structure and Ansible task format. It doesn't check variable values, module parameters, or runtime conditions.
Related Articles
• Ansible template vs copy module • managing Windows hosts with Ansible • become_user and become_method in Ansible • Ansible inventory file structure • understanding Ansible rolesSee also
• Holiday Greetings from Ansible Pilot: Merry Christmas & New Year!Category: installation
Watch the video: Ansible Syntax Error: Debug & Fix YAML Playbook Errors (Guide) — Video Tutorial