Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Ansible By James Joyner IV · · 6 min read

Ansible Error: 'hosts is required but was not set' — Cause, Fix, and Troubleshooting Guide

Quick answer

Fix Ansible's 'the field hosts is required but was not set' error: add a hosts key to each play or fix a malformed playbook structure.

Part of the Ansible Playbook & Module Errors hub
  • #ansible
  • #troubleshooting
  • #automation
  • #playbooks
Free toolkit

Fixing errors like this? Get 500 free DevOps AI prompts

500 copy-paste AI prompts for the stack you actually run — one PDF, free.

Overview

Every play in a playbook must declare which hosts it targets via the hosts keyword. If a play dictionary is missing hosts — usually because of an indentation slip, a stray list item, or a task written where a play belongs — Ansible refuses to load it:

ERROR! the field 'hosts' is required but was not set

This is a structural error caught at parse time.

Symptoms

  • The playbook fails to start; no host runs.
  • It often follows adding a second play or re-indenting a block.
  • --syntax-check reproduces it every time.
ansible-playbook -i inventory.ini site.yml --syntax-check
ERROR! the field 'hosts' is required but was not set

Common Root Causes

1. A play with no hosts key

You wrote tasks: at the top level without a surrounding play that names hosts.

2. Indentation merged a play into the wrong level

A dedent turned what should be a task list into a second, malformed play.

3. A stray list item at play level

An extra - creates an empty/partial play dict with no hosts.

4. Tasks file run as a playbook

Running a file that only contains tasks (meant for include_tasks) with ansible-playbook.

How to diagnose

Syntax-check and read the structure:

ansible-playbook site.yml --syntax-check

A playbook is a list of plays; each play is a dict with hosts. Confirm the top-level shape:

python3 -c 'import yaml,sys; d=yaml.safe_load(open("site.yml")); print(type(d), [list(p.keys()) for p in d])'

Each play’s key list should include hosts.

Fixes

Give every play a hosts key

- name: Configure web tier
  hosts: web            # required
  become: true
  tasks:
    - name: Install nginx
      ansible.builtin.apt:
        name: nginx
        state: present

- name: Configure db tier
  hosts: db             # second play also needs its own hosts
  tasks:
    - name: Install postgres
      ansible.builtin.apt:
        name: postgresql
        state: present

Do not run a tasks file as a playbook

A tasks-only file must be included, not executed directly:

# site.yml
- hosts: web
  tasks:
    - ansible.builtin.include_tasks: install.yml

Remove stray list markers

Delete any lone - that creates an empty play dict.

What to watch out for

  • A playbook is always a list of plays at the top level; a bare mapping of tasks is not a valid playbook.
  • Use hosts: localhost (with connection: local) for control-node-only plays rather than omitting hosts.
  • yamllint plus --syntax-check in CI catches this before it reaches a real inventory.
Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.