Ansible Cfg Not Working | Fix Search Order And Paths

Ansible often ignores your ansible.cfg because it loaded a different config file, or a higher-priority override replaced your setting.

You tweak a value in ansible.cfg, run ansible-playbook, and nothing changes. Same inventory, same SSH behavior, same output. It feels like the config got ignored.

Most of the time, the file is fine. Ansible is just using a different config file than you think, or a higher-priority source is overriding what you set. Once you prove what is active, the fix turns into a short, clear set of steps.

This article gives you a practical path: identify the config file Ansible loaded, confirm which values are in effect, then remove the override that is blocking your change. You will also see a few pitfalls that show up in WSL, Vagrant, containers, and CI runners.

Ansible Cfg Not Working In Your Repo

When ansible cfg not working pops up in a project, start with one assumption: Ansible did not load the file you edited. That sounds blunt, yet it is the fastest mindset for getting unstuck.

There are three usual reasons. You edited the right file but ran the command from a different folder. You edited the file in the current folder, but Ansible skipped it due to a safety check. Or your setting is being overridden by a command line flag or an ANSIBLE_* variable.

Before you change anything else, run these two commands and look at the lines they print:

  • Show the config file path – Run ansible --version and find the line that says config file.
  • Show active values with their source – Run ansible-config dump --only-changed to see what is different from defaults and where it came from.

If the config file line points to a file you never touched, that is your answer. Your edits are sitting in a different place. If the dump shows your setting coming from env: or cli:, your config entry is losing the fight.

Config File Search Order And What Wins

Ansible searches for ansible.cfg in a fixed order and uses the first file it finds. After it finds one, it stops. Any other config files that exist on the same machine get ignored for that run.

This is the standard search order Ansible uses for the config file:

Search Step Where Ansible Looks What This Usually Means
1 ANSIBLE_CONFIG variable If set, it overrides the file search
2 ansible.cfg in the current working folder Project-level config, used when step 1 is not set
3 ~/.ansible.cfg User config that applies across projects
4 /etc/ansible/ansible.cfg System-wide defaults, used as a fallback

That order explains a lot of mystery. If your shell sets ANSIBLE_CONFIG, the project file will not be used. If you run playbooks from a folder that does not contain ansible.cfg, Ansible will keep searching until it finds a user or system file.

If you want a project config to apply every time, pick one of these patterns and stick to it:

  • Run commands from the project root – Keep ansible.cfg in that folder and run ansible and ansible-playbook from there.
  • Set ANSIBLE_CONFIG in your run script – Export the full path to the intended config file, then call Ansible from anywhere.

Once you settle on one pattern, ansible cfg not working stops showing up in day-to-day work.

Ansible.cfg Not Working In The Current Directory

There is one rule that catches people off guard: Ansible will not auto-load ansible.cfg from the current working directory if that directory is world-writable. If anyone on the system can drop a file there, a malicious config could run code in places you never expected. Ansible avoids that risk by skipping the current-folder config in that case.

When this happens, you will often see a warning that mentions a world-writable directory and says it is ignoring that directory as a config source. This is common on synced folders, WSL mounts under /mnt, some container volumes, and CI workspaces.

Fixing it is not hard. You just need to make the folder safe or point Ansible at a config file stored in a safe path.

  • Remove world write from the folder – Adjust permissions so the directory is not writable by group or others.
  • Fix synced-folder permission mapping – On Vagrant or file shares, change the mount settings so files are writable only by the intended user.
  • Set ANSIBLE_CONFIG explicitly – Export ANSIBLE_CONFIG=/full/path/to/ansible.cfg in your shell or pipeline, then run Ansible from any folder.

If you use the explicit variable route, keep it visible in your scripts. Hidden exports are a classic cause of config drift between terminals, CI jobs, and teammates.

Read The Active Config Like A Detective

You do not need to guess which settings are active. Ansible can show you the config file path, the merged values, and the source of each value.

Start with a quick snapshot, then zoom in:

  1. Capture the reported config file – Run ansible --version and copy the path shown next to config file.
  2. Dump changed settings only – Run ansible-config dump --only-changed and scan for the setting you edited.
  3. Check the source tag – Look for markers like cfg:, env:, or cli: next to the value.
  4. Find the active config fast – Run ansible-config dump | grep CONFIG_FILE to see what Ansible selected.

Commands You Can Copy And Run

ansible --version
ansible-config dump --only-changed
ansible-config dump | grep CONFIG_FILE
printenv | grep ^ANSIBLE_

If a setting you expected is missing from the dump, Ansible is not reading it. If the setting is present but has env: or cli:, your config file entry is losing to a higher-priority source.

Want a clean, fast sanity check? Change one setting that is easy to spot in output, then rerun the dump and a tiny playbook. Two good choices are stdout_callback and diff_always.

Fix Settings That Seem Ignored

Even with the right config file, a setting can still feel like it does nothing. That usually means something else is overriding it, or the entry is not parsed the way you expect.

Command Line Flags Beat The File

Anything you pass on the command line wins. This often happens with inventory paths, remote user, forks, and privilege escalation.

  • Scan your command – Look for flags like -i, -u, -f, -b, -K, and --ssh-common-args.
  • Compare against the dump – The config dump shows when a value comes from cli:.

ANSIBLE_* Variables Can Override Single Options

Many options have a matching ANSIBLE_* variable. If you exported one months ago, it can silently win every time you open a terminal.

  • List current ANSIBLE_* variables – Run printenv | grep ^ANSIBLE_ and look for anything related to your issue.
  • Unset and retest – Remove the variable for one run and see if the behavior changes.

INI Details That Trip People Up

Ansible uses an INI-style config file. A small formatting slip can make an entry look valid while being read in an unexpected way.

  • Use the right section – Put most core settings under [defaults], SSH options under [ssh_connection], and become options under [privilege_escalation].
  • Use semicolon for inline comments – A # works when it starts a line. For inline comments, use ; so the value is not cut off.
  • Match the option name exactly – If you are not sure, run ansible-config list and search for the setting.
  • Stick to plain booleans – Use True and False where an option expects a boolean.

Generate A Clean Starting File

If your config file has grown messy, generating a fresh template can reset the noise without losing your intent. Create a fully commented template, then copy only the lines you plan to change.

ansible-config init --disabled > ansible.cfg
ansible-config init --disabled -t all > ansible.full.cfg

After you move your settings over, rerun ansible-config dump --only-changed. You should see your changes listed with a cfg: source tag.

Paths, Relative Values, And Why They Shift

Some options in ansible.cfg point to paths: inventory, roles, collections, log files, callback plugins, and more. Relative paths can behave in a way that feels random when you are switching between configs without realizing it.

In many cases, relative paths are resolved relative to the config file that was loaded. That can be great in a tidy repo, yet it can be confusing when Ansible is using a different config file on a different machine.

Clean Ways To Set Inventory And Roles Paths

  • Keep project paths local – Store inventory.ini, group_vars, and roles/ under the same repo root as your ansible.cfg.
  • Use absolute paths in CI – Build paths from the CI workspace root so the run does not depend on where the shell started.
  • Log what Ansible loads – Set log_path to a file you can archive in CI so you can inspect runs when something changes.

Watch Out For Hidden Defaults

Even if /etc/ansible/ansible.cfg looks blank, Ansible still has compiled-in defaults. A file with many commented lines is still a valid config. Ansible reads defaults, then applies your changes from the active config, then applies any overrides from variables and the CLI.

If you are chasing a path bug, do not stop at the file. Use the dump output as your source of truth for what is actually active.

Quick Stability Checklist For Ansible Config

Once you fix the immediate issue, take two minutes to make sure it does not come back next week. These checks keep config behavior predictable across machines and runners.

  • Keep one project root – Run playbooks from a consistent folder, and store ansible.cfg at that root.
  • Prefer explicit config in automation – In CI, export ANSIBLE_CONFIG so the job never relies on the current directory.
  • Audit ANSIBLE_* exports – Remove stale exports from shell profiles and pipeline templates.
  • Pin versions when possible – Keep ansible-core versions consistent so defaults and plugin availability do not jump between hosts.
  • Recheck after permission changes – If you move a repo into a synced folder, rerun ansible --version to confirm the config file is still being loaded.

If you follow the steps in this article, you will be able to point at a single config file and say, “This is the one Ansible used.” That is the moment ansible.cfg stops feeling mysterious.

If you use ansible-navigator or an automation platform, the same rules apply. Check the working directory of the runner, then check the reported config file path in job output. If you cannot change permissions, set ANSIBLE_CONFIG in the job template or wrapper script. After each change, rerun ansible-config dump –only-changed to confirm the new source tags before you ship a run to production today with confidence.