{"record":{"id":"dc7950771789e4fa","repo":"hashicorp/vagrant","slug":"ansible-failed-to-complete-successfully-any-error-dc7950","errorCode":null,"errorMessage":"Ansible failed to complete successfully. Any error output should be\nvisible above. Please fix these errors and try again.","messagePattern":"Ansible failed to complete successfully\\. Any error output should be\nvisible above\\. Please fix these errors and try again\\.","errorType":"exception","errorClass":"VagrantPlugins::Ansible::Errors.AnsibleCommandFailed","httpStatus":null,"severity":"error","filePath":"plugins/provisioners/ansible/provisioner/host.rb","lineNumber":107,"sourceCode":"        def prepare_environment_variables\n          prepare_common_environment_variables\n\n          # Some Ansible options must be passed as environment variables,\n          # as there is no equivalent command line arguments\n          @environment_variables[\"ANSIBLE_HOST_KEY_CHECKING\"] = \"#{config.host_key_checking}\"\n\n          # ANSIBLE_SSH_ARGS is required for Multiple SSH keys, SSH forwarding and custom SSH settings\n          @environment_variables[\"ANSIBLE_SSH_ARGS\"] = ansible_ssh_args unless ansible_ssh_args.empty?\n        end\n\n        def execute_command_from_host(command)\n          begin\n            result = Vagrant::Util::Subprocess.execute(*command) do |type, data|\n              if type == :stdout || type == :stderr\n                @machine.env.ui.detail(data, new_line: false, prefix: false)\n              end\n            end\n            raise Ansible::Errors::AnsibleCommandFailed if result.exit_code != 0\n          rescue Vagrant::Errors::CommandUnavailable\n            raise Ansible::Errors::AnsibleNotFoundOnHost\n          end\n        end\n\n        def gather_ansible_version(package = 'ansible')\n          raw_output = ''\n          command = ['python3', '-c',\n                     \"import importlib.metadata; print('#{package} ' + importlib.metadata.version('#{package}'))\"]\n\n          command << {\n            notify: [:stdout, :stderr]\n          }\n\n          begin\n            result = Vagrant::Util::Subprocess.execute(*command) do |type, output|\n              if type == :stdout && output.lines[0]\n                raw_output = output","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/hashicorp/vagrant/blob/35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5/plugins/provisioners/ansible/provisioner/host.rb#L89-L125","documentation":"Host-mode ansible execution shells out via Vagrant::Util::Subprocess and streams stdout/stderr to the UI detail output; a non-zero exit raises AnsibleCommandFailed. It also maps Vagrant::Errors::CommandUnavailable (ansible binary not on PATH) to AnsibleNotFoundOnHost — this specific site raises the command-failed variant only when ansible did run and failed. The actionable failure output is above the error in the log.","triggerScenarios":"execute_command_from_host running the assembled `ansible-playbook ...` command where Subprocess result.exit_code != 0 — failing tasks, ssh connection refused from host to guest, playbook syntax errors, missing roles on the host.","commonSituations":"Host cannot ssh to the guest on the forwarded port (custom ssh settings, firewalls); role/collection not installed on host; inventory generated under .vagrant/provisioners references a stale address after `vagrant reload`; ansible.cfg on the host overriding settings unexpectedly.","solutions":["Read the ansible output printed just above the error — it names the failing task/host","Confirm host->guest ssh works: use the command from `vagrant provision` output with `--verbose`, or `vagrant ssh-config` to check the port/address","Install missing dependencies on the host (`ansible-galaxy install -r requirements.yml`) or wire them via ansible.galaxy_role_file","Set `ansible.verbose = true` (or \"vvv\") and re-run `vagrant provision` for full detail"],"exampleFix":"# Vagrantfile — before (role not installed on host)\nconfig.vm.provision \"ansible\" do |ansible|\n  ansible.playbook = \"site.yml\"   # site.yml uses geerlingguy.nginx\nend\n# after — let Vagrant install roles before the run\nconfig.vm.provision \"ansible\" do |ansible|\n  ansible.playbook = \"site.yml\"\n  ansible.galaxy_role_file = \"requirements.yml\"\nend","handlingStrategy":"try-catch","validationCode":"require 'mkmf'\nabort 'ansible-playbook not on PATH' unless find_executable('ansible-playbook')\nsystem('ansible-playbook', '--syntax-check', playbook_path) or abort 'playbook fails syntax check'","typeGuard":"def ansible_playbook_runnable?(playbook_path)\n  !find_executable('ansible-playbook').nil? && system('ansible-playbook', '--syntax-check', playbook_path, out: File::NULL)\nend","tryCatchPattern":"begin\n  machine.provision\nrescue Ansible::Errors::AnsibleCommandFailed\n  # output already streamed via ui.detail; surface a summary and stop the pipeline\n  raise 'ansible playbook failed - see provisioner output above'\nrescue Ansible::Errors::AnsibleNotFoundOnHost\n  raise 'install ansible on the host first (pipx install ansible)'\nend","preventionTips":["Run `ansible-playbook --syntax-check` on the playbook in CI before `vagrant provision`","Pre-install roles/collections (galaxy_role_file / galaxy_collection_file) so runs don't fail on missing deps","After `vagrant reload`, remember generated inventory addresses change - re-provision, don't cache them"],"tags":["ansible","provisioner","host","playbook","exit-code","subprocess"],"backgroundTag":"ansible-playbook-failed","analyzedSha":"35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5","analyzedAt":"2026-08-21T13:34:32.514Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}