hashicorp/vagrant · error · Vagrant::Errors::BoxVersionInvalid

The format of box version provided (%{version}) is incorrect

Error message

The format of box version provided (%{version}) is incorrect. The version must follow the semantic versioning format or semantic versioning compatible constraint format. Examples of valid values:

  2.0
  2.1.4
  >= 2
  < 3.0.0

What it means

BoxVersionInvalid is raised in BoxCollection#find (lib/vagrant/box_collection.rb:325) when Gem::Requirement.new(v.strip) raises BadRequirementError while parsing each comma-separated constraint from the version argument. Versions must be semantic-version strings or semver-compatible constraints as parsed by RubyGems.

Source

Thrown at lib/vagrant/box_collection.rb:325

    # Find a box in the collection with the given name and provider.
    #
    # @param [String] name Name of the box (logical name).
    # @param [Array] providers Providers that the box implements.
    # @param [String] version Version constraints to adhere to. Example:
    #   "~> 1.0" or "= 1.0, ~> 1.1"
    # @return [Box] The box found, or `nil` if not found.
    def find(name, providers, version, box_architecture=:auto)
      providers = Array(providers)
      architecture = box_architecture
      architecture = Util::Platform.architecture if architecture == :auto

      # Build up the requirements we have
      requirements = version.to_s.split(",").map do |v|
        begin
          Gem::Requirement.new(v.strip)
        rescue Gem::Requirement::BadRequirementError
          raise Errors::BoxVersionInvalid,
                version: v.strip
        end
      end

      with_collection_lock do
        box_directory = @directory.join(dir_name(name))
        if !box_directory.directory?
          @logger.info("Box not found: #{name} (#{providers.join(", ")})")
          return nil
        end

        # Keep a mapping of Gem::Version mangled versions => directories.
        # ie. 0.1.0.pre.alpha.2 => 0.1.0-alpha.2
        # This is so we can sort version numbers properly here, but still
        # refer to the real directory names in path checks below and pass an
        # unmangled version string to Box.new
        version_dir_map = {}

View on GitHub (pinned to 35f3160f4a)

Solutions

  1. Use valid semver or constraint syntax: exact '2.1.4', or '>= 2', '< 3.0.0', '= 2.0', '~> 1.0', and comma-separated combos like '= 1.0, ~> 1.1'
  2. Fix the source of the string: correct config.vm.box_version in the Vagrantfile or the --box-version CLI flag
  3. Omit the version entirely if any version is acceptable

Example fix

# before (Vagrantfile)
config.vm.box_version = "v2.0"

# after
config.vm.box_version = "~> 2.0"
Defensive patterns

Strategy: validation

Validate before calling

def valid_box_version?(str)
  str.to_s.split(',').all? { |part| (Gem::Requirement.new(part.strip) rescue nil) }
end
raise 'bad box_version' unless valid_box_version?(config_version)

Prevention

When it happens

Trigger: find(name, providers, version) is called with a version string whose segments are not valid RubyGems requirements — e.g. '--box-version "2..0"', '>= ', or 'v2.0' via 'vagrant box add/update/remove --box-version', or config.vm.box_version in the Vagrantfile. Each comma part is tried with Gem::Requirement and the failing fragment is reported.

Common situations: Typos in config.vm.box_version; using 'latest' or 'v1.2.3' style tags; copy-pasting constraints from non-semver release pages; trailing commas producing an empty fragment.

Related errors


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