{"record":{"id":"41b98ad498988fdb","repo":"ansible/ansible","slug":"detected-range-in-host-but-was-asked-to-ignore-ran","errorCode":null,"errorMessage":"Detected range in host but was asked to ignore ranges","messagePattern":"Detected range in host but was asked to ignore ranges","errorType":"validation","errorClass":"AnsibleParserError","httpStatus":null,"severity":"error","filePath":"lib/ansible/parsing/utils/addresses.py","lineNumber":212,"sourceCode":"    # What we're left with now must be an IPv4 or IPv6 address, possibly with\n    # numeric ranges, or a hostname with alphanumeric ranges.\n\n    host = None\n    for matching in ['ipv4', 'ipv6', 'hostname']:\n        m = patterns[matching].match(address)\n        if m:\n            host = address\n            continue\n\n    # If it isn't any of the above, we don't understand it.\n    if not host:\n        raise AnsibleError(\"Not a valid network hostname: %s\" % address)\n\n    # If we get to this point, we know that any included ranges are valid.\n    # If the caller is prepared to handle them, all is well.\n    # Otherwise we treat it as a parse failure.\n    if not allow_ranges and '[' in host:\n        raise AnsibleParserError(\"Detected range in host but was asked to ignore ranges\")\n\n    return (host, port)\n","sourceCodeStart":194,"sourceCodeEnd":215,"githubUrl":"https://github.com/ansible/ansible/blob/9cf16a4aca7898481c257f1e17ad28d0b67b1f85/lib/ansible/parsing/utils/addresses.py#L194-L215","documentation":"Raised by parse_address() in lib/ansible/parsing/utils/addresses.py when the string parsed successfully as a host pattern containing one or more '[' range specifications (e.g. foo[1:3].example.com) but the caller passed allow_ranges=False. The pattern is valid, but the caller explicitly declined to accept ranges, so it is treated as a parse failure via AnsibleParserError.","triggerScenarios":"Calling parse_address('web[01:05]', allow_ranges=False), which is the default; any code path that needs one concrete host (e.g. connection plugins resolving a single target) hitting inventory range syntax that was never expanded by the inventory layer.","commonSituations":"A playbook passes a range pattern like 'web[1:3]' directly to add_host, a module parameter, or a connection setting where only a single host is meaningful; the pattern failed to expand earlier (misconfigured inventory plugin or pattern used outside inventory context); user assumes bracket ranges are shell globbing rather than Ansible inventory syntax.","solutions":["Expand the range before parsing: use ansible.plugins.inventory.expand_hostname_range() or ansible.utils.display helpers to turn 'web[1:3]' into individual hosts, then call parse_address() on each.","If you actually want a single host, remove the '[...]' range syntax and pass the literal hostname.","If your code genuinely supports patterns, call parse_address(address, allow_ranges=True) and handle the range yourself."],"exampleFix":"# before\nhost, port = parse_address('web[01:03]')  # raises\n# after\nfrom ansible.plugins.inventory import expand_hostname_range\nfor h in expand_hostname_range('web[01:03]'):\n    host, port = parse_address(h)","handlingStrategy":"validation","validationCode":"from ansible.parsing.utils.addresses import parse_address\n\ndef parse_single_host(address: str):\n    # reject inventory range syntax before it reaches parse_address\n    if '[' in address or ']' in address:\n        raise ValueError(f'range pattern not allowed here: {address!r} — expand it first')\n    return parse_address(address, allow_ranges=False)","typeGuard":null,"tryCatchPattern":"from ansible.errors import AnsibleParserError, AnsibleError\nfrom ansible.parsing.utils.addresses import parse_address\ntry:\n    host, port = parse_address(address)\nexcept AnsibleParserError as e:  # range in host\n    hosts = expand_hostname_range(address)\n    results = [parse_address(h) for h in hosts]\nexcept AnsibleError:\n    raise","preventionTips":["Decide explicitly whether a code path accepts patterns; pass allow_ranges=True only where you handle ranges.","Expand inventory ranges with expand_hostname_range() before single-host APIs like connection settings.","Keep bracket range syntax inside inventory definitions, not module arguments."],"tags":["ansible","inventory","hostname","range","parsing"],"backgroundTag":null,"analyzedSha":"9cf16a4aca7898481c257f1e17ad28d0b67b1f85","analyzedAt":"2026-08-15T00:15:47.100Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}