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

The requested Ansible compatibility mode (%{compatibility_mo

Error message

The requested Ansible compatibility mode (%{compatibility_mode}) is in conflict with
the Ansible installation on your Vagrant %{system} system (currently: %{ansible_version}).
See https://docs.vagrantup.com/v2/provisioning/ansible_common.html#compatibility_mode
for more information.

What it means

The Ansible provisioner probes the installed ansible/ansible-core version and, when the Vagrantfile explicitly requests compatibility_mode "2.0" while the detected major version is < 2, it raises AnsibleCompatibilityModeConflict. The mode controls which option lexicon Vagrant emits (1.8 vs 2.0), so declaring 2.0 against an ansible 1.x install would generate unsupported flags. AUTO mode never raises here — it detects instead.

Source

Thrown at plugins/provisioners/ansible/provisioner/base.rb:80

            set_gathered_ansible_version(gather_ansible_version("ansible"))
          rescue StandardError => e
            # Nothing to do here, as the fallback on safe compatibility_mode is done below
            @logger.error("Error while gathering the ansible version: #{e.to_s}")
          end

          begin
            set_gathered_ansible_package_version("ansible-core", gather_ansible_version("ansible-core"))
          rescue StandardError => e
             @logger.error("Error while gathering the ansible-core version: #{e}")
          end
          
          if @gathered_version_major
            if config.compatibility_mode == Ansible::COMPATIBILITY_MODE_AUTO
              detect_compatibility_mode
            elsif @gathered_version_major.to_i < 2 && config.compatibility_mode == Ansible::COMPATIBILITY_MODE_V2_0
              # A better version comparator will be needed
              # when more compatibility modes come... but so far let's keep it simple!
              raise Ansible::Errors::AnsibleCompatibilityModeConflict,
                ansible_version: @gathered_version,
                system: @control_machine,
                compatibility_mode: config.compatibility_mode
            end
          end

          if config.compatibility_mode == Ansible::COMPATIBILITY_MODE_AUTO
            config.compatibility_mode = Ansible::SAFE_COMPATIBILITY_MODE

            @machine.env.ui.warn(I18n.t("vagrant.provisioners.ansible.compatibility_mode_not_detected",
              compatibility_mode: config.compatibility_mode,
              gathered_version: @gathered_version_stdout) +
            "\n")
          end

          unless Ansible::COMPATIBILITY_MODES.slice(1..-1).include?(config.compatibility_mode)
            raise Ansible::Errors::AnsibleProgrammingError,
              message: "The config.compatibility_mode must be correctly set at this stage!",

View on GitHub (pinned to 35f3160f4a)

Solutions

  1. Upgrade ansible on the controlling machine to >= 2.0 (`pip install -U ansible` or the distro package)
  2. Or set `ansible.compatibility_mode = "auto"` / remove the pin so Vagrant picks the right lexicon for what is installed
  3. Or set compatibility_mode = "1.8" if you must keep the old ansible
  4. Verify which ansible is detected: run `ansible --version` with the same user/environment vagrant uses (and `python3 -c "import importlib.metadata; print(importlib.metadata.version('ansible'))"`)

Example fix

# Vagrantfile — before (host runs ansible 1.9.x)
ansible.compatibility_mode = "2.0"
# after — let Vagrant match the installed version
ansible.compatibility_mode = "auto"
Defensive patterns

Strategy: validation

Validate before calling

installed = `ansible --version 2>/dev/null`[/ansible[^\n]* ([\d.]+)/, 1] || `python3 -c "import importlib.metadata; print(importlib.metadata.version('ansible'))" 2>/dev/null`
abort 'ansible >= 2.0 required for compatibility_mode 2.0' if installed && installed.split('.').first.to_i < 2

Type guard

def ansible_supports_v2?
  v = `python3 -c "import importlib.metadata; print(importlib.metadata.version('ansible'))" 2>/dev/null`.to_s.split('.').first.to_i
  v >= 2
end

Prevention

When it happens

Trigger: set_and_check_compatibility_mode runs during provision; @gathered_version_major.to_i < 2 while config.compatibility_mode == Ansible::COMPATIBILITY_MODE_V2_0 ("2.0" in the Vagrantfile) — i.e. host or guest has ansible 1.9.x or older installed and the Vagrantfile pins mode "2.0".

Common situations: Legacy hosts still on ansible 1.9; a base box shipping ancient ansible while the Vagrantfile was written for modern ansible; installing ansible via pip into a different python than the one probed (so detection reads the old system copy); upgrading Vagrant changed the default and someone pinned "2.0" blindly.

Related errors


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