Ansible Error Guide: 'the role ... was not found'
Fix Ansible's ERROR! the role was not found error: diagnose roles_path, missing galaxy roles, requirements.yml, collection roles, and wrong role names or directory layout.
- #ansible
- #troubleshooting
- #errors
- #roles
Overview
This error is raised at parse time when a playbook references a role that Ansible cannot find in any of its search paths. Ansible looks for roles in roles/ next to the playbook, then in directories listed in roles_path, then in installed collections. If the role’s directory does not exist in any of those, parsing stops with the role ... was not found.
You will see it immediately, before any task runs:
ERROR! the role 'nginx' was not found in /home/deploy/site/roles:/home/deploy/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
The error appears to be in '/home/deploy/site/site.yml': line 6, column 7
Helpfully, the message lists every directory it searched. The role is missing from all of them. The fix is almost always to install the role (from requirements.yml), correct the role name, or add the right directory to roles_path.
Symptoms
ansible-playbookfails instantly withthe role '...' was not found in <paths>.- The error enumerates the search paths it checked.
- The play works on one machine but not a CI runner (role installed in different places).
- A collection-provided role is referenced without its FQCN.
ansible-playbook -i inventory.ini site.yml --syntax-check
ERROR! the role 'geerlingguy.docker' was not found in /home/deploy/site/roles:/home/deploy/.ansible/roles:/etc/ansible/roles
Common Root Causes
1. The Galaxy role was never installed
The role is declared in requirements.yml but not installed on this control node.
cat requirements.yml
roles:
- name: geerlingguy.docker
- name: geerlingguy.nginx
ansible-galaxy role list 2>/dev/null | grep -i docker
(No output means it is not installed.) Install:
ansible-galaxy role install -r requirements.yml
2. roles_path does not include the role’s location
The role exists, but in a directory Ansible does not search.
ansible-config dump | grep -i roles_path
ls -d roles/*/ 2>/dev/null
DEFAULT_ROLES_PATH(default) = ['/home/deploy/.ansible/roles', '/etc/ansible/roles']
If your roles live in ./galaxy_roles/ but that is not on roles_path, they are invisible. Add it in ansible.cfg.
3. Typo in the role name
geerlingguy.docker typed as geerlingguy.dcoker, or webserver vs web-server.
ERROR! the role 'webserver' was not found ...
ls roles/
ansible-galaxy role list 2>/dev/null
Compare the available role names to what the play references.
4. Role directory missing the expected structure
A directory exists under roles/ but lacks tasks/main.yml (and meta/), so Ansible does not treat it as a role.
ls -la roles/nginx/ roles/nginx/tasks/ 2>/dev/null
ls: cannot access 'roles/nginx/tasks/': No such file or directory
Without tasks/main.yml (or another recognized subdir), the role is “not found”.
5. A collection role referenced without its FQCN
Roles can ship inside collections and must be called as namespace.collection.role.
roles:
- nginx # actually lives in nginxinc.nginx_core
ERROR! the role 'nginx' was not found ...
ansible-galaxy collection list 2>/dev/null | grep -i nginx
Reference it by FQCN: nginxinc.nginx_core.nginx.
6. Roles installed to a per-user path not present in CI
The role is installed under ~/.ansible/roles for one user but the play runs as another (or in a container) where that path is empty.
ansible-galaxy role install -r requirements.yml -p ./roles
ls roles/
Installing into a project-local ./roles makes the role portable across environments.
Diagnostic Workflow
Step 1: Read the searched paths from the error
ERROR! the role 'docker' was not found in /home/deploy/site/roles:/home/deploy/.ansible/roles:/etc/ansible/roles
These are exactly the directories Ansible checked — the role is in none of them.
Step 2: List what roles are actually available
ls -d roles/*/ 2>/dev/null
ansible-galaxy role list 2>/dev/null
This shows project-local and Galaxy-installed roles to compare against the requested name.
Step 3: Confirm requirements vs. installed
cat requirements.yml
ansible-galaxy role list 2>/dev/null
ansible-galaxy collection list 2>/dev/null
A role in requirements.yml but absent from the lists was never installed here.
Step 4: Check roles_path and structure
ansible-config dump | grep -i roles_path
ls -la roles/<role>/tasks/main.yml 2>/dev/null
Confirm both that the path is searched and that the directory is a valid role.
Step 5: Install/declare correctly and re-check
ansible-galaxy install -r requirements.yml -p ./roles
ansible-playbook -i inventory.ini site.yml --syntax-check
A clean syntax check confirms the role now resolves.
Example Root Cause Analysis
A deploy that works on a developer laptop fails in CI:
ERROR! the role 'geerlingguy.postgresql' was not found in /builds/ops/site/roles:/root/.ansible/roles:/etc/ansible/roles
The role name is correct and the play is unchanged. Listing roles on the runner:
ansible-galaxy role list 2>/dev/null
# /root/.ansible/roles
(empty)
No roles are installed. On the laptop the developer had run ansible-galaxy install -r requirements.yml once, long ago, into ~/.ansible/roles. The CI container starts fresh every run and never installs the requirements — the missing install step in the pipeline is the root cause.
Fix: install requirements into a project-local path as a pipeline step so it is deterministic and committed-adjacent:
ansible-galaxy install -r requirements.yml -p ./roles
ansible-galaxy role list 2>/dev/null | grep postgresql
- geerlingguy.postgresql, 3.5.2
The syntax check passes and the deploy runs.
Prevention Best Practices
- Declare all external roles (with versions) in
requirements.ymland runansible-galaxy install -r requirements.ymlas an explicit step in CI and on every control node. - Install into a project-local
./roles(-p ./roles) and commit a.gitignorefor it, so the role layout is identical everywhere instead of depending on per-user~/.ansible/roles. - Pin a
roles_pathin a committedansible.cfgso the search path is reproducible regardless of who runs the play. - Use FQCN for collection-provided roles (
namespace.collection.role) and runansible-lint, which flags unresolved and short-named roles. - Validate with
--syntax-checkin CI before deploy; it catches missing roles without touching a host. - For diagnosing role-resolution failures that differ between environments, the free incident assistant can compare the searched paths to what is installed. See more in the Ansible guides.
Quick Command Reference
# Surface the missing role and searched paths
ansible-playbook -i inventory.ini site.yml --syntax-check
# What roles are available?
ls -d roles/*/ 2>/dev/null
ansible-galaxy role list 2>/dev/null
ansible-galaxy collection list 2>/dev/null # for collection-provided roles
# What does Ansible search?
ansible-config dump | grep -i roles_path
# Is the role a valid structure?
ls -la roles/<role>/tasks/main.yml
# Install requirements into a project-local path
ansible-galaxy install -r requirements.yml -p ./roles
Conclusion
the role '...' was not found is a parse-time failure: the role is in none of the directories Ansible searched (which the error lists). The usual root causes:
- A Galaxy role declared in
requirements.ymlbut never installed here. - The role’s directory is not on
roles_path. - A typo in the role name.
- A
roles/<name>/directory missingtasks/main.yml(not a valid role). - A collection role referenced without its FQCN.
- Roles installed in a per-user path absent in CI/containers.
Read the searched paths, compare them to ansible-galaxy role list, and install requirements into a project-local ./roles — that makes role resolution reproducible across laptops, servers, and CI.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.