4 min read

Debugging and troubleshooting Ansible Playbooks

March 2, 2026
Debugging and troubleshooting Ansible Playbooks

Table of contents

The debugging workflowError type 1: YAML syntax errorsError type 2: Indentation errorsError type 3: Module name typosPro tip: Modern Ansible requires Fully Qualified Class Name (FQCN) for clarity. Always use `ansible.builtin.debug` not just `debug`.Error type 4: Host pattern mismatchesError type 5: Undefined variablesAscender Pro advantage: Visual debuggingUsing the debug module effectivelyvar vs msgConditional debuggingDebugging registered variablesQuick reference: Error typesPre-flight troubleshooting checklistNext steps

Subscribe to our newsletter

Subscribe

The error says "line 11, column 5" but line 11 looks fine. Sound familiar?

Ansible error messages can be cryptic. A missing space breaks everything. A typo in a variable name fails silently until three tasks later. YAML indentation errors point to the wrong line.

This guide gives you a systematic approach to diagnosing and fixing the most common Ansible playbook errors.

What you'll learn:

  • How to read Ansible error messages (they're more helpful than they look)
  • The 5 most common error types and how to fix each one
  • Using the debug module effectively
  • How Ascender Pro makes debugging dramatically easier

Series: Ansible development best practices

  • Part A: Achieving idempotency
  • Part B: Debugging and troubleshooting (you are here)
  • Part C: Mastering nested loops (coming soon)
  • Part D: Enterprise features (coming soon)

The debugging workflow

When a playbook fails, follow this sequence:

  1. Read the error message — Line number, column, and error type
  2. Check syntax first — YAML formatting causes most failures
  3. Verify variable names — Typos won't error until runtime
  4. Test incrementally — Comment out sections to isolate problems
  5. Use debug tasks — Print variables to understand state

Error type 1: YAML syntax errors

Error message:

Unable to read either as JSON nor YAML
Line 1, column 1

Common causes:

  • Wrong number of dashes at start (must be exactly three: ---)
  • Tab characters instead of spaces
  • Missing colon after key names

Fix:

# WRONG - four dashes
----
- name: My playbook

# CORRECT - three dashes
---
- name: My playbook

Pro tip: Configure your editor to show whitespace characters and convert tabs to spaces.


Error type 2: Indentation errors

Error message:

did not find expected key
Line 11, column 5

Common causes:

  • Inconsistent indentation levels
  • Mixing tabs and spaces
  • Tasks not aligned under tasks:

Why does the error point to the wrong line?

YAML parsers report where they detected the problem, not where it occurred. When indentation breaks, the parser often doesn't realize it until 1-3 lines later when it encounters something that doesn't fit the broken structure.

Debugging tip: If the error says "line 11" but line 11 looks fine, check lines 8-10 for:

  • Inconsistent indentation
  • Missing colons
  • Tasks not properly nested under `tasks:`

This is why the error message says "line 11, column 5" even though line 11 is perfectly valid YAML.

Fix:

# WRONG - debug not indented under task
 tasks:
 - name: Display variable
 ansible.builtin.debug:
   var: my_variable

 # CORRECT - consistent 2-space indentation
 tasks:
  - name: Display variable
    ansible.builtin.debug:
      var: my_variable

VS Code shortcut: Select lines and press Ctrl + ] to indent right, Ctrl + [ to indent left.

Pro tip: Use a YAML syntax linter such as yamllint to catch syntax errors


Error type 3: Module name typos

Error message:

ERROR! no action detected in task. This often indicates a misspelled module name

Common causes:

  • Misspelled module names
  • Wrong FQCN (Fully Qualified Collection Name)

Fix:

# WRONG - typo in module name
- name: Display message
  ansible.builtin.degub:  # "degub" instead of "debug"
    msg: "Hello"

# CORRECT
- name: Display message
  ansible.builtin.debug:
    msg: "Hello"

Pro tip: Modern Ansible requires Fully Qualified Class Name (FQCN) for clarity. Always use `ansible.builtin.debug` not just `debug`.

Error type 4: Host pattern mismatches

Error message:

Could not match supplied host pattern, ignoring: webservers

Common causes:

  • Host/group doesn't exist in inventory
  • Host is disabled
  • Typo in hostname or group name

Fix: Verify the host exists and is enabled in your inventory. In Ascender Pro, go to Inventories → [Your Inventory] → Hosts and search.

# Fragile - typo breaks everything
- hosts: server_123.example.com

# Resilient - group membership managed separately
- hosts: webservers

Error type 5: Undefined variables

Error message:

The task includes an option with an undefined variable

Common causes:

  • Variable not registered before use
  • Typo in variable name
  • Variable out of scope (defined in different play)

Fix: Use debug to inspect available variables:

- name: Show all variables
  ansible.builtin.debug:
    var: vars

- name: Show specific variable
  ansible.builtin.debug:
    var: my_variable

- name: Show with context
  ansible.builtin.debug:
    msg: "The value is {{ my_variable | default('NOT DEFINED') }}"

The | default('NOT DEFINED') filter prevents the error and shows you what's missing.


Debug without the guesswork

Ascender Pro captures complete JSON output for every task. Click any task to see all variables, return values, and host metadata — no debug tasks required.

Try Ascender Pro →


Ascender Pro advantage: Visual debugging

image1

Command-line debugging means adding debug tasks, running the playbook, reading scroll-back, editing, and repeating. Ascender Pro changes this:

Debugging task CLI Ansible Ascender Pro
See variable values Add debug task, rerun View actual JSON
Find where it failed Scroll through output Color-coded, click to expand
Compare to last successful run Hope you saved the output Side-by-side job comparison
Share failure with teammate Copy/paste terminal Send job URL

"Update revision on launch" is especially valuable for debugging:

  1. Edit playbook in your IDE
  2. Commit to Git
  3. Click "Launch" in Ascender Pro (auto-syncs repo)
  4. View results immediately

No manual sync step. No "forgot to pull latest" issues.


Using the debug module effectively

var vs msg

# var: Shows variable name and structure
- name: Display with var
  ansible.builtin.debug:
    var: users.stdout_lines
# Output: "users.stdout_lines": ["root", "admin", "deploy"]

# msg: Shows just the value with custom text
- name: Display with msg
  ansible.builtin.debug:
    msg: "Found {{ users.stdout_lines | length }} users"
# Output: "msg": "Found 3 users"

Conditional debugging

Only show debug output when running with increased verbosity:

- name: Verbose-only debug info
  ansible.builtin.debug:
    msg: "Detailed info: {{ complex_variable }}"
  when: ansible_verbosity >= 2

Debugging registered variables

When a registered variable doesn't contain what you expect:

- name: Run command
  ansible.builtin.shell: cat /etc/passwd
  register: passwd_output

- name: See what we got
  ansible.builtin.debug:
    var: passwd_output

# Shows: stdout, stdout_lines, stderr, rc, changed, etc.

This reveals the full structure so you know whether to use .stdout, .stdout_lines, or something else.


Quick reference: Error types

Error message Likely cause First thing to check
"Unable to read as JSON nor YAML" YAML syntax Dash count, tabs vs. spaces
"did not find expected key" Indentation Alignment under parent
"conflicting action statements" Module typo Spelling of module name
"Could not match host pattern" Inventory issue Host exists and enabled
"undefined variable" Variable scope/typo Variable name spelling, registration order
"Permission denied" Credentials SSH key, become password
"unreachable" Connectivity Network, SSH, host online

Pre-flight troubleshooting checklist

Before asking for help, verify:

  • Playbook has correct YAML syntax (three dashes, spaces not tabs)
  • All module names are spelled correctly
  • Variables are defined before use
  • Host patterns match inventory entries
  • Hosts are enabled in inventory
  • Changes are committed to Git AND pushed to remote
  • Project is synced (or "Update on launch" is enabled)
  • You've checked the JSON output for variable structure
  • You've compared to a previous successful run

Next steps

Playbook working but running slowly?

Continue with Part C: Mastering nested loops (coming soon) to learn efficient iteration patterns.

Want visual debugging and 90-day job history?

Try Ascender Pro to see how enterprise features transform your debugging workflow.

Built for Scale. Chosen by the World’s Best.

1.4M+

Rocky Linux instances

Being used world wide

90%

Of fortune 100 companies

Use CIQ supported technologies

250k

Avg. monthly downloads

Rocky Linux

Related posts

Achieving idempotency with shell commands

Achieving idempotency with shell commands

Ansible Import vs. Include: What’s the Real Difference?

Ansible Import vs. Include: What’s the Real Difference?

Compliance Automation with Ascender Pro

Compliance Automation with Ascender Pro

CVE management: automate discovery to remediation

CVE management: automate discovery to remediation