{"record":{"id":"e8fb9657b988ee65","repo":"ansible/ansible","slug":"specified-inventory-host-pattern-and-or-limit-l","errorCode":null,"errorMessage":"Specified inventory, host pattern and/or --limit leaves us with no hosts to target.","messagePattern":"Specified inventory, host pattern and/or --limit leaves us with no hosts to target\\.","errorType":"exception","errorClass":"AnsibleError","httpStatus":null,"severity":"error","filePath":"lib/ansible/cli/__init__.py","lineNumber":602,"sourceCode":"        for host in inventory.list_hosts():\n            hostname = host.get_name()\n            variable_manager.clear_facts(hostname)\n\n    @staticmethod\n    def get_host_list(inventory, subset, pattern='all'):\n\n        no_hosts = False\n        if len(inventory.list_hosts()) == 0:\n            # Empty inventory\n            if C.LOCALHOST_WARNING and pattern not in C.LOCALHOST:\n                display.warning(\"provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'\")\n            no_hosts = True\n\n        inventory.subset(subset)\n\n        hosts = inventory.list_hosts(pattern)\n        if not hosts and no_hosts is False:\n            raise AnsibleError(\"Specified inventory, host pattern and/or --limit leaves us with no hosts to target.\")\n\n        return hosts\n\n    @staticmethod\n    def get_password_from_file(pwd_file: str) -> str:\n        b_pwd_file = to_bytes(pwd_file)\n\n        if b_pwd_file == b'-':\n            # ensure its read as bytes\n            secret = sys.stdin.buffer.read()\n\n        elif not os.path.exists(b_pwd_file):\n            raise AnsibleError(\"The password file %s was not found\" % pwd_file)\n\n        elif is_executable(b_pwd_file):\n            display.vvvv(u'The password file %s is a script.' % to_text(pwd_file))\n            cmd = [b_pwd_file]\n","sourceCodeStart":584,"sourceCodeEnd":620,"githubUrl":"https://github.com/ansible/ansible/blob/9cf16a4aca7898481c257f1e17ad28d0b67b1f85/lib/ansible/cli/__init__.py#L584-L620","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nansible webservers --limit prod-1 -m ping\n# ERROR: Specified inventory, host pattern and/or --limit leaves us with no hosts to target.\n\n# after\nansible-inventory --graph          # discover real names\nansible web --limit prod-web-1 -m ping","handlingStrategy":"validation","validationCode":"import subprocess, json, sys\n\ndef hosts_for(inventory: str, pattern: str, limit: str | None = None) -> list[str]:\n    cmd = ['ansible-inventory', '-i', inventory, '--list']\n    inv = json.loads(subprocess.check_output(cmd))\n    return list(inv.get('_meta', {}).get('hostvars', {}).keys())\n\n# before ansible.run():\ntargets = hosts_for('hosts.ini', 'webservers')\nif not targets:\\n    sys.exit('no hosts matched; check pattern/inventory before running ansible')","typeGuard":null,"tryCatchPattern":"from ansible.errors import AnsibleError\n\ntry:\\n    hosts = cli.get_host_list(inventory, 0, pattern, subset_str)\nexcept 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","preventionTips":["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."],"tags":["inventory","host-pattern","limit","no-hosts","ansible-cli"],"backgroundTag":null,"analyzedSha":"9cf16a4aca7898481c257f1e17ad28d0b67b1f85","analyzedAt":"2026-08-15T00:15:47.100Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}