hashicorp/vagrant · error · VagrantPlugins::Ansible::Errors.AnsibleError
`%{config_option}` does not exist on the %{system}: %{path}
Error message
`%{config_option}` does not exist on the %{system}: %{path} What it means
Before provisioning, host-mode ansible validates configured paths (playbook, inventory_path, config_file, galaxy files) by expanding them relative to the Vagrantfile's root_path and applying a File test (file?/exist?). A failing check raises the localized AnsibleError 'config_file_not_found' naming the option and resolved absolute path. It is a plain path-existence validation on the host filesystem.
Source
Thrown at plugins/provisioners/ansible/provisioner/host.rb:333
# Re-enable ControlPersist Ansible defaults,
# which are lost when ANSIBLE_SSH_ARGS is defined.
unless ssh_options.empty?
ssh_options << "-o ControlMaster=auto"
ssh_options << "-o ControlPersist=60s"
# Intentionally keep ControlPath undefined to let ansible-playbook
# automatically sets this option to Ansible default value
end
ssh_options.join(' ')
end
def check_path(path, path_test_method, option_name)
# Checks for the existence of given file (or directory) on the host system,
# and error if it doesn't exist.
expanded_path = Pathname.new(path).expand_path(@machine.env.root_path)
if !expanded_path.public_send(path_test_method)
raise Ansible::Errors::AnsibleError,
_key: :config_file_not_found,
config_option: option_name,
path: expanded_path,
system: @control_machine
end
end
def check_path_is_a_file(path, option_name)
check_path(path, "file?", option_name)
end
def check_path_exists(path, option_name)
check_path(path, "exist?", option_name)
end
end
end
endView on GitHub (pinned to 35f3160f4a)
Solutions
- Compare the resolved absolute path in the error with the real file location and fix the Vagrantfile option
- Use paths relative to the Vagrantfile root (they are expanded with root_path), or absolute paths for outside files
- If the file is generated, ensure the generating provisioner/shell step runs first
- On case-sensitive filesystems, verify filename casing exactly
Example fix
# Vagrantfile — before ansible.playbook = "playbok.yml" # after ansible.playbook = "playbook.yml"
Defensive patterns
Strategy: validation
Validate before calling
expanded = File.expand_path(relative_path, project_root)
raise "#{option_name} not found: #{expanded}" unless File.public_send(file_test, expanded) # file? or exist? Type guard
def host_path_valid?(path, root_path, must_be_file: true) p = Pathname.new(path.to_s).expand_path(root_path) must_be_file ? p.file? : p.exist? end
Prevention
- Keep playbooks/inventories inside the project root and reference them relatively
- In CI, check paths case-sensitively even if developing on macOS
- If files are generated, order provisioners so the generator runs before ansible
When it happens
Trigger: check_path_is_a_file / check_path_exists (called from check_files_existence before `vagrant provision` runs ansible on the host) with a path that doesn't resolve — typo'd filename, path written relative to the project root when it's elsewhere, or files generated later by another provisioner that haven't been created yet.
Common situations: Typo in `ansible.playbook = "playbok.yml"`; playbook living outside the project while given as a relative path; inventory file created by an earlier step that was skipped; case-sensitivity differences between macOS (dev) and Linux (CI) paths.
Related errors
- The requested Ansible version (%{required_version}) was not
- Ansible failed to complete successfully. Any error output sh
- The requested Ansible compatibility mode (%{compatibility_mo
- Ansible Provisioner Programming Error: %{message} Internal
- The requested Ansible version (%{required_version}) was not
AI-assisted analysis of hashicorp/vagrant@35f3160f4a (2026-08-21).
Data as JSON: /api/errors/3af35d527e1e8cae.
Report an issue: GitHub.