Introduction

The parser-error rule in ansible-lint fires when your playbook has YAML syntax problems that prevent Ansible from parsing the file at all. Unlike other lint rules that check best practices, parser errors mean the playbook cannot run — they must be fixed before anything else.

The Rule

Rule name: parser-error Severity: Fatal Tags: core, unskippable

This rule cannot be skipped — it represents genuine syntax errors that make the playbook unparseable.

Common Causes and Fixes

1. Missing Space After Colon

The most frequent YAML mistake:

# WRONG — no space after colon
- name: Install apache
  ansible.builtin.apt:
    name:apache2
    state:present

# CORRECT — space after colon
- name: Install apache
  ansible.builtin.apt:
    name: apache2
    state: present

2. Inconsistent Indentation

YAML requires consistent spaces (never tabs):

# WRONG — mixed indentation (2 spaces vs 1 space)
- name: Install apache
  ansible.builtin.apt:
   name: apache2
    state: present

# CORRECT — consistent 2-space indentation
- name: Install apache
  ansible.builtin.apt:
    name: apache2
    state: present

3. Tabs Instead of Spaces

YAML forbids tabs entirely:

# WRONG — tab characters (invisible but fatal)
- name: Install package
	ansible.builtin.apt:
		name: nginx

# CORRECT — spaces only
- name: Install package
  ansible.builtin.apt:
    name: nginx

Detect tabs:

grep -P '\t' playbook.yml

4. Unquoted Special Characters

Colons, brackets, and other YAML special characters in values need quoting:

# WRONG — colon in unquoted value
- name: Set message
  ansible.builtin.debug:
    msg: Error: something failed

# CORRECT — quoted string
- name: Set message
  ansible.builtin.debug:
    msg: "Error: something failed"
# WRONG — curly braces interpreted as YAML mapping
- name: Show variable
  ansible.builtin.debug:
    msg: {{ my_var }}

# CORRECT — quoted Jinja2 expression
- name: Show variable
  ansible.builtin.debug:
    msg: "{{ my_var }}"

5. Wrong List Format

# WRONG — missing dash or wrong indentation
- name: Install packages
  ansible.builtin.apt:
    name:
    nginx
    curl

# CORRECT — proper list with dashes
- name: Install packages
  ansible.builtin.apt:
    name:
      - nginx
      - curl

6. Duplicate Keys

# WRONG — duplicate 'name' key
- name: Install packages
  ansible.builtin.apt:
    name: nginx
    name: curl  # Overwrites first 'name'

# CORRECT — use a list
- name: Install packages
  ansible.builtin.apt:
    name:
      - nginx
      - curl

7. Incorrect Boolean/String Mixing

# WRONG — 'yes' without quotes can be parsed as boolean in some contexts
- name: Set variable
  ansible.builtin.set_fact:
    answer: yes please  # YAML parses 'yes' as True

# CORRECT — quote the string
- name: Set variable
  ansible.builtin.set_fact:
    answer: "yes please"

8. Missing Document Start

# WRONG — missing --- at start
- name: My playbook
  hosts: all
  tasks: []

# CORRECT — document start marker
---
- name: My playbook
  hosts: all
  tasks: []

Debugging Parser Errors

Check Syntax Before Running

# Ansible's built-in syntax check
ansible-playbook --syntax-check playbook.yml

# ansible-lint (catches more issues)
ansible-lint playbook.yml

# Python YAML parser (shows exact line/column)
python3 -c "import yaml; yaml.safe_load(open('playbook.yml'))"

Find the Exact Error Location

ansible-lint output shows the file and line:

playbook.yml:8:5: parser-error: syntax error - mapping values are not allowed here

This means line 8, column 5 has the issue.

VS Code Integration

Install the Ansible extension for VS Code — it highlights parser errors in real-time:

code --install-extension redhat.ansible

The extension shows:

  • Red underlines for syntax errors
  • Yellow for warnings
  • Hover tooltips with fix suggestions

YAML Quick Reference

# Strings
name: simple string
name: "quoted: with special chars"
name: 'single quoted: literal'
name: |
  multi-line
  block scalar
name: >
  folded into
  single line

# Lists
items:
  - first
  - second
  - third

# Inline list
items: [first, second, third]

# Dictionary
config:
  key1: value1
  key2: value2

# Inline dictionary
config: {key1: value1, key2: value2}

# Boolean (use true/false, not yes/no)
enabled: true
debug: false

# Null
value: null
value: ~

Prevention Tips

  1. Use a YAML-aware editor — VS Code with Ansible extension
  2. Set editor to spaces-only — 2 spaces per indent, no tabs
  3. Always quote Jinja2 — "{{ variable }}" not {{ variable }}
  4. Always quote strings with colons — "key: value" not key: value
  5. Run ansible-lint before committing — catch errors early
  6. Add pre-commit hook for automatic linting

Editor Configuration (.editorconfig)

# .editorconfig
[*.{yml,yaml}]
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

Conclusion

Parser errors are the most fundamental ansible-lint rule — they mean your YAML is broken and the playbook won't run at all. The fix is almost always one of: add a space after a colon, fix indentation to consistent 2-space, quote strings with special characters, or replace tabs with spaces. Use ansible-playbook --syntax-check for quick validation, and set up your editor with the Ansible extension to catch these errors as you type.