hashicorp/vagrant · error · VagrantPlugins::Ansible::Errors.AnsibleVersionMismatch

The requested Ansible version (%{required_version}) was not

Error message

The requested Ansible version (%{required_version}) was not found on the %{system}.
Please check the Ansible installation on your Vagrant %{system} system (currently: %{current_version}),
or adapt the provisioner `version` option in your Vagrantfile.
See https://docs.vagrantup.com/v2/provisioning/ansible_common.html#version
for more information.

What it means

For the ansible provisioner running inside the guest, after installing/verifying ansible and gathering its version, Vagrant compares config.version (when set and not :latest) against the version importlib.metadata reports in the guest. A mismatch raises AnsibleVersionMismatch naming the required vs current version. The check intentionally tolerates :latest and empty values.

Source

Thrown at plugins/provisioners/ansible/provisioner/guest.rb:70

            return
          end

          # Try to install Ansible (if needed and requested)
          if config.install &&
             (config.version.to_s.to_sym == :latest ||
              !@machine.guest.capability(:ansible_installed, config.version))
            @machine.ui.detail I18n.t("vagrant.provisioners.ansible.installing")
            @machine.guest.capability(:ansible_install, config.install_mode, config.version, config.pip_args, config.pip_install_cmd)
          end

          # This step will also fetch the Ansible version data into related instance variables
          set_and_check_compatibility_mode

          # Check if requested ansible version is available
          if (!config.version.empty? &&
              config.version.to_s.to_sym != :latest &&
              config.version != @gathered_version)
            raise Ansible::Errors::AnsibleVersionMismatch,
              system: @control_machine,
              required_version: config.version,
              current_version: @gathered_version
          end
        end

        def gather_ansible_version(package = 'ansible')
          raw_output = ""

          result = @machine.communicate.execute(
            "python3 -c \"import importlib.metadata; print('#{package} ' + importlib.metadata.version('#{package}'))\"",
            error_class: Ansible::Errors::AnsibleNotFoundOnGuest,
            error_key: :ansible_not_found_on_guest) do |type, output|
            if type == :stdout && output.lines[0]
              raw_output = output.lines[0]
            end
          end

View on GitHub (pinned to 35f3160f4a)

Solutions

  1. Align the Vagrantfile: set `ansible.version` to the exact version installed in the guest, or to "latest"
  2. If an install was expected, check install_mode/pip_args actually installed the requested release (watch the 'installing' detail output during provisioning)
  3. Re-run with VAGRANT_LOG=info to see which version was gathered from the guest
  4. Uninstall the stale guest ansible (`pip uninstall ansible`) so the requested version gets installed on the next run

Example fix

# Vagrantfile — before (guest actually has 2.9.27)
ansible.version = "2.9.9"
# after
ansible.version = "latest"
Defensive patterns

Strategy: validation

Validate before calling

# guest-side: verify the pinned version exists in the guest before provisioning
# vagrant ssh -c 'python3 -c "import importlib.metadata; print(importlib.metadata.version(\'ansible\'))"'
# compare that output to ansible.version in the Vagrantfile before `vagrant provision`

Type guard

def guest_ansible_version_matches?(machine, required)
  out = ''
  machine.communicate.execute('python3 -c "import importlib.metadata; print(importlib.metadata.version(\'ansible\'))"') { |_, d| out << d }
  required.to_s == 'latest' || required.to_s == out.strip.sub('ansible ', '')
end

Prevention

When it happens

Trigger: Guest provisioning where config.version is set (e.g. "2.9.9") but the guest's installed ansible (gathered via `python3 -c "import importlib.metadata; ..."`) reports a different string — version present but different, install_mode did not install the requested release, or pip_args overrode it.

Common situations: install_mode = "pip" with a version pip no longer serves, so the guest keeps its preinstalled ansible; base box already ships a different ansible; version string mismatch ("2.10" vs "2.10.0"); config.version typo'd in the Vagrantfile.

Related errors


AI-assisted analysis of hashicorp/vagrant@35f3160f4a (2026-08-21). Data as JSON: /api/errors/7361916a841bf0a4. Report an issue: GitHub.