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

  1. List what the inventory actually contains: ansible-inventory --list (or ansible <pattern> --list-hosts) and compare against your pattern and --limit value.
  2. Fix the host pattern or --limit value to match an existing host/group name exactly.
  3. If using a dynamic inventory source, verify it returns hosts (check credentials, filters, region).
  4. Check inventory_sources (ANSIBLE_INVENTORY) to confirm the right inventory files are being loaded.
  5. 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

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


AI-assisted analysis of ansible/ansible@9cf16a4aca (2026-08-15). Data as JSON: /api/errors/e8fb9657b988ee65. Report an issue: GitHub.