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

The box you're attempting to add already exists. Remove it b

Error message

The box you're attempting to add already exists. Remove it before adding it again or add it with the `--force` flag.

Name: %{name}
Provider: %{provider}
Version: %{version}

What it means

BoxAlreadyExists is raised inside the check_box_exists lambda in BoxCollection#add (lib/vagrant/box_collection.rb:95) when find() locates an existing box with the same name/provider/version and opts[:force] is not set. With --force the code instead logs and destroys the old box directory before continuing.

Source

Thrown at lib/vagrant/box_collection.rb:95

    #   the box represents will be added.
    # @param [Boolean] force If true, any existing box with the same name
    #   and provider will be replaced.
    def add(path, name, version, **opts)
      architecture = opts[:architecture]
      providers = opts[:providers]
      providers = Array(providers) if providers
      provider = nil

      # A helper to check if a box exists. We store this in a variable
      # since we call it multiple times.
      check_box_exists = lambda do |box_formats, box_architecture|
        box = find(name, box_formats, version, box_architecture)
        next if !box

        if !opts[:force]
          @logger.error(
            "Box already exists, can't add: #{name} v#{version} #{box_formats.join(", ")}")
          raise Errors::BoxAlreadyExists,
            name: name,
            provider: box_formats.join(", "),
            version: version
        end

        # We're forcing, so just delete the old box
        @logger.info(
          "Box already exists, but forcing so removing: " +
          "#{name} v#{version} #{box_formats.join(", ")}")
        box.destroy!
      end

      with_collection_lock do
        log_provider = providers ? providers.join(", ") : "any provider"
        @logger.debug("Adding box: #{name} (#{log_provider} - #{architecture.inspect}) from #{path}")

        # Verify the box doesn't exist early if we're given a provider. This
        # can potentially speed things up considerably since we don't need

View on GitHub (pinned to 35f3160f4a)

Solutions

  1. Pass --force to overwrite: 'vagrant box add <src> --name <n> --force' (the source shows the old box is destroyed first)
  2. Or remove the existing entry: 'vagrant box remove <name> --provider <p> [--box-version <v>]', then add again
  3. In scripts, make the add conditional: skip when 'vagrant box list' already shows the name/provider/version you need

Example fix

# before
vagrant box add ./mybox.box --name corp/mybox

# after
vagrant box remove corp/mybox --provider virtualbox
vagrant box add ./mybox.box --name corp/mybox
# or simply
vagrant box add ./mybox.box --name corp/mybox --force
Defensive patterns

Strategy: validation

Validate before calling

existing = collection.find(name, [provider], version)
collection.add(path, name: name, provider: provider, version: version, force: existing.nil?)

Prevention

When it happens

Trigger: 'vagrant box add' (or a re-run of it / automation script) for a name+provider+version tuple that already exists under the collection directory; find(name, box_formats, version, box_architecture) returns a Box and the force flag is absent, so the error is raised with the colliding name, provider list and version.

Common situations: Re-running provisioning pipelines that add the same box twice; upgrading a box by re-adding the same version; multiple developers' bootstrap scripts adding a shared internal box.

Related errors


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