Indentation errors are the most common Ansible problem — and the most frustrating. YAML relies entirely on whitespace for structure, so a single misaligned space can break an entire playbook. This guide covers how to read YAML error messages, the most common indentation mistakes, and tools to prevent them.

Why YAML Indentation Matters

YAML uses indentation (spaces, never tabs) to define structure:

  • 2 spaces is the Ansible convention (though any consistent number works)
  • Tabs are not allowed — YAML parsers reject them
  • Indentation defines hierarchy — child elements must be indented more than parents
  • Siblings must align — items at the same level must have identical indentation

Common Error Messages

"could not find expected ':'"

ERROR! Syntax Error while loading YAML.
  mapping values are not allowed in this context
  The error appears to be in 'playbook.yml': line 7, column 25

This means a value is at the wrong indentation level.

"We were unable to read either as JSON nor YAML"

ERROR! We were unable to read either as JSON nor YAML, these are the errors we got:
YAML: mapping values are not allowed here

Usually caused by tabs mixed with spaces or inconsistent indentation.

The 5 Most Common Indentation Mistakes

1. Task Not Indented Under tasks:

Wrong:

---
- name: Install packages
  hosts: all
  become: true
  tasks:
- name: Install nginx
  ansible.builtin.apt:
    name: nginx
    state: present

Correct:

---
- name: Install packages
  hosts: all
  become: true
  tasks:
    - name: Install nginx
      ansible.builtin.apt:
        name: nginx
        state: present

The task (- name: Install nginx) must be indented under tasks:.

2. Module Parameters Not Indented Under Module

Wrong:

    - name: Install nginx
      ansible.builtin.apt:
      name: nginx
      state: present

Correct:

    - name: Install nginx
      ansible.builtin.apt:
        name: nginx
        state: present

Module parameters (name, state) must be indented further than the module name.

3. Mixing Tabs and Spaces

Wrong (invisible but broken):

    - name: Install nginx
      ansible.builtin.apt:
	    name: nginx    # This line uses a tab!
        state: present

Fix: Configure your editor to use spaces only. In VS Code:

{
  "editor.insertSpaces": true,
  "editor.tabSize": 2,
  "editor.detectIndentation": false
}

4. Inconsistent Indentation Depth

Wrong:

    - name: Install nginx
      ansible.builtin.apt:
          name: nginx     # 6 spaces (wrong)
        state: present    # 4 spaces (inconsistent)

Correct:

    - name: Install nginx
      ansible.builtin.apt:
        name: nginx       # 4 spaces (consistent)
        state: present    # 4 spaces (consistent)

5. Block/When/Loop at Wrong Level

Wrong:

    - name: Install nginx
      ansible.builtin.apt:
        name: nginx
        state: present
        when: ansible_os_family == "Debian"  # Wrong! when is not a module parameter

Correct:

    - name: Install nginx
      ansible.builtin.apt:
        name: nginx
        state: present
      when: ansible_os_family == "Debian"  # Aligned with the module name

Task-level directives (when, loop, register, become, notify) must be at the same level as the module name, not indented under it.

How to Read YAML Error Messages

Ansible error messages include line and column numbers:

ERROR! Syntax Error while loading YAML.
  The error appears to be in '/home/user/playbook.yml': line 12, column 5

Tips:

  • The error is often on the line before the reported line
  • Column number tells you the exact indentation position
  • Look for the first line where indentation breaks the pattern

Tools to Prevent Indentation Errors

1. ansible-playbook --syntax-check

ansible-playbook playbook.yml --syntax-check

Catches YAML parsing errors before running.

2. ansible-lint

pip install ansible-lint
ansible-lint playbook.yml

Catches style issues beyond basic syntax — including indentation inconsistencies.

3. yamllint

pip install yamllint
yamllint playbook.yml

Dedicated YAML linter with configurable rules:

# .yamllint
rules:
  indentation:
    spaces: 2
    indent-sequences: true
  line-length:
    max: 160
  truthy:
    allowed-values: ['true', 'false']

4. VS Code Ansible Extension

The Red Hat Ansible extension provides real-time indentation error highlighting. See our VS Code for Ansible guide.

5. Pre-commit Hooks

Automate linting before every commit:

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/adrienverge/yamllint
    rev: v1.35.1
    hooks:
      - id: yamllint
  - repo: https://github.com/ansible/ansible-lint
    rev: v24.2.0
    hooks:
      - id: ansible-lint

YAML Indentation Quick Reference

---                              # Document start
- name: Play name                # Play (list item, 0 indent)
  hosts: all                     #   Play keyword (2 spaces)
  become: true                   #   Play keyword (2 spaces)
  vars:                          #   Play keyword (2 spaces)
    my_var: value                #     Variable (4 spaces)
  tasks:                         #   Play keyword (2 spaces)
    - name: Task name            #     Task (4 spaces, list item)
      ansible.builtin.apt:      #       Module (6 spaces)
        name: nginx              #         Parameter (8 spaces)
        state: present           #         Parameter (8 spaces)
      when: condition            #       Task directive (6 spaces)
      register: result           #       Task directive (6 spaces)
      loop:                      #       Task directive (6 spaces)
        - item1                  #         Loop item (8 spaces)
        - item2                  #         Loop item (8 spaces)
  handlers:                      #   Play keyword (2 spaces)
    - name: Handler name         #     Handler (4 spaces)
      ansible.builtin.service:   #       Module (6 spaces)
        name: nginx              #         Parameter (8 spaces)
        state: restarted         #         Parameter (8 spaces)

Conclusion

YAML indentation errors are preventable with the right tools and habits. Use 2-space indentation consistently, configure your editor to insert spaces (never tabs), and run ansible-playbook --syntax-check before every execution. For teams, enforce standards with yamllint and ansible-lint in CI/CD pipelines and pre-commit hooks. Once you internalize the indentation hierarchy — play → task → module → parameters — these errors become rare.