ansible/ansible · error · AnsibleError
Specified inventory, host pattern and/or --limit leaves us w
Error message
Specified inventory, host pattern and/or --limit leaves us with no hosts to target.
What it means
Raised as AnsibleError by CLI.get_host_list when the resolved inventory, combined with the host pattern and any --limit subset, matches zero hosts. After inventory.subset(subset) applies the limit, inventory.list_hosts(pattern) returning an empty list (while the inventory itself was not empty) triggers this error. It is the standard 'no hosts matched' failure for ad-hoc commands and playbooks.
Source
Thrown at lib/ansible/cli/__init__.py:602
for host in inventory.list_hosts():
hostname = host.get_name()
variable_manager.clear_facts(hostname)
@staticmethod
def get_host_list(inventory, subset, pattern='all'):
no_hosts = False
if len(inventory.list_hosts()) == 0:
# Empty inventory
if C.LOCALHOST_WARNING and pattern not in C.LOCALHOST:
display.warning("provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'")
no_hosts = True
inventory.subset(subset)
hosts = inventory.list_hosts(pattern)
if not hosts and no_hosts is False:
raise AnsibleError("Specified inventory, host pattern and/or --limit leaves us with no hosts to target.")
return hosts
@staticmethod
def get_password_from_file(pwd_file: str) -> str:
b_pwd_file = to_bytes(pwd_file)
if b_pwd_file == b'-':
# ensure its read as bytes
secret = sys.stdin.buffer.read()
elif not os.path.exists(b_pwd_file):
raise AnsibleError("The password file %s was not found" % pwd_file)
elif is_executable(b_pwd_file):
display.vvvv(u'The password file %s is a script.' % to_text(pwd_file))
cmd = [b_pwd_file]
View on GitHub (pinned to 9cf16a4aca)
Solutions
- List what the inventory actually contains: ansible-inventory --list (or ansible <pattern> --list-hosts) and compare against your pattern and --limit value.
- Fix the host pattern or --limit value to match an existing host/group name exactly.
- If using a dynamic inventory source, verify it returns hosts (check credentials, filters, region).
- Check inventory_sources (ANSIBLE_INVENTORY) to confirm the right inventory files are being loaded.
- Handle 'empty inventory is OK' cases in automation by testing host count first via ansible-inventory --graph instead of letting the run fail.
Example fix
# before ansible webservers --limit prod-1 -m ping # ERROR: Specified inventory, host pattern and/or --limit leaves us with no hosts to target. # after ansible-inventory --graph # discover real names ansible web --limit prod-web-1 -m ping
Defensive patterns
Strategy: validation
Validate before calling
import subprocess, json, sys
def hosts_for(inventory: str, pattern: str, limit: str | None = None) -> list[str]:
cmd = ['ansible-inventory', '-i', inventory, '--list']
inv = json.loads(subprocess.check_output(cmd))
return list(inv.get('_meta', {}).get('hostvars', {}).keys())
# before ansible.run():
targets = hosts_for('hosts.ini', 'webservers')
if not targets:\n sys.exit('no hosts matched; check pattern/inventory before running ansible') Try / catch
from ansible.errors import AnsibleError
try:\n hosts = cli.get_host_list(inventory, 0, pattern, subset_str)
except AnsibleError as e:\n if 'no hosts to target' in str(e):\n # graceful: log and skip this batch instead of failing the whole pipeline\n logger.warning('empty target set for pattern=%s limit=%s', pattern, subset_str)\n hosts = []\n else:\n raise Prevention
- Validate patterns/limits with `ansible <pattern> --list-hosts` (or ansible-inventory) in a preflight CI step.
- Treat an empty target set as an expected condition in automation and check it explicitly instead of relying on the error.
- Keep --limit values generated from the same inventory source to avoid drift between environments.
When it happens
Trigger: Running 'ansible <pattern> -m ping' where the pattern matches no inventory host; using --limit with a group or hostname that does not exist in the inventory (or is excluded by it); a pattern typo; --limit referencing hosts from a different inventory source; using a dynamic inventory whose query returns nothing; combining --limit with a pattern whose intersection is empty.
Common situations: Typo'd hostname or group name; --limit value copied from another environment's inventory; dynamic inventory (cloud) returning zero instances because the environment is empty or credentials filter everything out; host pattern 'webservers*' when group is named 'web'; child group removed but limit still used in CI scripts.
Related errors
- You must pass a single valid host to --host parameter
- ERROR: Ansible requires the locale encoding to be UTF-8; Det
- ERROR: Ansible requires the filesystem encoding to be UTF-8;
- The password file %s was not found
- Problem occurred when trying to run the password script %s (
AI-assisted analysis of ansible/ansible@9cf16a4aca (2026-08-15).
Data as JSON: /api/errors/e8fb9657b988ee65.
Report an issue: GitHub.