ansible/ansible · error · AnsibleError

Unable to load data from include requirements file: %s %s

Error message

Unable to load data from include requirements file: %s %s

What it means

Raised as a catch-all when an included requirements file (the legacy 'include:' mechanism) exists and was opened, but either its YAML could not be parsed or a role entry inside it failed to parse (the list comprehension calling RoleRequirement.role_yaml_parse is wrapped in a bare 'except Exception'). The original exception text is appended so the root cause is visible.

Source

Thrown at lib/ansible/cli/galaxy.py:802

        def parse_role_req(requirement):
            if "include" not in requirement:
                role = RoleRequirement.role_yaml_parse(requirement)
                display.vvv("found role %s in yaml file" % to_text(role))
                if "name" not in role and "src" not in role:
                    raise AnsibleError("Must specify name or src for role")
                return [GalaxyRole(self.galaxy, self.lazy_role_api, **role)]
            else:
                b_include_path = to_bytes(requirement["include"], errors="surrogate_or_strict")
                if not os.path.isfile(b_include_path):
                    raise AnsibleError("Failed to find include requirements file '%s' in '%s'"
                                       % (to_native(b_include_path), to_native(requirements_file)))

                with open(b_include_path, 'rb') as f_include:
                    try:
                        return [GalaxyRole(self.galaxy, self.lazy_role_api, **r) for r in
                                (RoleRequirement.role_yaml_parse(i) for i in yaml_load(f_include))]
                    except Exception as e:
                        raise AnsibleError("Unable to load data from include requirements file: %s %s"
                                           % (to_native(requirements_file), to_native(e)))

        if isinstance(file_requirements, list):
            # Older format that contains only roles
            if not allow_old_format:
                raise AnsibleError("Expecting requirements file to be a dict with the key 'collections' that contains "
                                   "a list of collections to install")

            for role_req in file_requirements:
                requirements['roles'] += parse_role_req(role_req)

        elif isinstance(file_requirements, dict):
            # Newer format with a collections and/or roles key
            extra_keys = set(file_requirements.keys()).difference(set(['roles', 'collections']))
            if extra_keys:
                raise AnsibleError("Expecting only 'roles' and/or 'collections' as base keys in the requirements "
                                   "file. Found: %s" % (to_native(", ".join(extra_keys))))

View on GitHub (pinned to 9cf16a4aca)

Solutions

  1. Read the appended original error in the message — it names the real failure (YAML syntax vs role parsing).
  2. Ensure the included file is a YAML list of role entries (name/src), not the newer requirements dict format.
  3. Lint the included file standalone with ansible-galaxy or a YAML parser to find the offending entry.
  4. Inline the roles into the parent file to remove the include indirection.

Example fix

# before (common.yml uses new format but is consumed via include:)
collections:
  - community.general

# after (common.yml must be a plain role list)
- name: geerlingguy.docker
- name: bertvv.samba
Defensive patterns

Strategy: validation

Validate before calling

import yaml

def validate_included_roles(path):
    data = yaml.safe_load(open(path))
    assert isinstance(data, list), "included file must be a YAML list of role entries"
    for e in data:
        assert isinstance(e, (str, dict)), f"bad role entry: {e!r}"

Try / catch

try:
    subprocess.run(cmd, check=True)
except subprocess.CalledProcessError as e:
    # message embeds the original parse error; surface it, fix the include file, re-run
    print(e.stderr)

Prevention

When it happens

Trigger: An 'include:' file whose contents are invalid YAML, or whose entries are not valid role specifications (e.g. a list of scalars that role_yaml_parse cannot interpret, or an unexpected exception while constructing GalaxyRole kwargs) triggers the except at lib/ansible/cli/galaxy.py:802.

Common situations: The included file was written in the newer dict format ('collections:' key) while the include mechanism expects a plain list of roles; partially written/truncated file from a concurrent process; wrong file substituted with the same name.

Related errors


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