Ansible Error: 'hosts is required but was not set' — Cause, Fix, and Troubleshooting Guide
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.
- #ansible
- #troubleshooting
- #automation
- #playbooks
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-checkreproduces 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(withconnection: local) for control-node-only plays rather than omittinghosts. yamllintplus--syntax-checkin CI catches this before it reaches a real inventory.
Related
- Ansible Error: ‘X is not a valid attribute for a Task’
- Ansible Error: ‘provided hosts list is empty’
- Ansible Error: ‘Syntax Error while loading YAML’
More Ansible prompts & error guides
Every Ansible AI prompt and troubleshooting guide, in one place.
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.