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 needView on GitHub (pinned to 35f3160f4a)
Solutions
- Pass --force to overwrite: 'vagrant box add <src> --name <n> --force' (the source shows the old box is destroyed first)
- Or remove the existing entry: 'vagrant box remove <name> --provider <p> [--box-version <v>]', then add again
- 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
- Make bootstrap scripts idempotent: skip 'vagrant box add' when 'vagrant box list' already shows the tuple
- Pass --force only when overwriting is intended; it destroys the existing box directory first
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
- The box you're attempting to add already exists. Remove it b
- You requested to remove the box '%{name}' version '%{version
- cloud-init is not found. Please ensure that cloud-init is in
- The "metadata.json" file for the box '%{name}' was not found
- The metadata associated with the box '%{name}' appears corru
AI-assisted analysis of hashicorp/vagrant@35f3160f4a (2026-08-21).
Data as JSON: /api/errors/48f175e1ff7b0703.
Report an issue: GitHub.