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
Errors::BoxAlreadyExists is raised during add_from_direct/add_from_metadata right before download: the box collection already contains the exact name+provider+version (and architecture) being added, and env[:box_force] (the --force flag) is not set.
Source
Thrown at lib/vagrant/action/builtin/box_add.rb:428
# @return [Box]
def box_add(urls, name, version, provider, md_url, env, **opts)
display_architecture = opts[:architecture] == :auto ?
Util::Platform.architecture : opts[:architecture]
env[:ui].output(I18n.t(
"vagrant.box_add_with_version",
name: name,
version: version,
providers: [
provider,
display_architecture ? "(#{display_architecture})" : nil
].compact.join(" ")))
# Verify the box we're adding doesn't already exist
if provider && !env[:box_force]
box = env[:box_collection].find(
name, provider, version, opts[:architecture])
if box
raise Errors::BoxAlreadyExists,
name: name,
provider: provider,
version: version
end
end
# Now we have a URL, we have to download this URL.
box = nil
begin
box_url = nil
urls.each do |url|
show_url = nil
if url.is_a?(Array)
show_url = url[1]
url = url[0]
end
View on GitHub (pinned to 35f3160f4a)
Solutions
- Pass --force (env[:box_force]) to overwrite the existing box entry.
- Remove the existing box first ('vagrant box remove NAME --provider P --box-version V') if you want a clean slate.
- For updates, prefer 'vagrant box update' inside the project rather than re-adding.
- In scripts, guard with 'vagrant box list' (or collection.find) before adding.
Example fix
# before vagrant box add hashicorp/bionic64 # already installed -> BoxAlreadyExists # after vagrant box add --force hashicorp/bionic64 # or remove then add vagrant box remove hashicorp/bionic64 && vagrant box add hashicorp/bionic64
Defensive patterns
Strategy: validation
Validate before calling
# Same check BoxAdd performs, done by the caller collection = env.box_collection if collection.find(name, provider, version, architecture) # already present: force overwrite or skip env[:box_force] = true end
Type guard
def box_installed?(collection, name, provider, version = nil, architecture = nil) !collection.find(name, provider, version, architecture).nil? end
Try / catch
begin
env.cli("box", "add", url)
rescue Vagrant::Errors::BoxAlreadyExists => e
# e.extra_data[:name], [:provider], [:version]
env.cli("box", "add", "--force", url)
end Prevention
- Make bootstrap scripts idempotent: check 'vagrant box list' (or collection.find) before adding.
- Use --force deliberately when re-adding to refresh a box; use 'vagrant box update' for in-place updates.
- Give CI jobs isolated VAGRANT_HOME when parallel adds are unavoidable.
When it happens
Trigger: A provider for the box is determined and env[:box_force] is falsy; env[:box_collection].find(name, provider, version, opts[:architecture]) returns an existing box; the raise carries name, provider, version.
Common situations: Re-running a bootstrap script that calls 'vagrant box add' on every run; re-adding a box to update it (wrong mental model - add does not upgrade in place); CI caching a ~/.vagrant.d between jobs.
Related errors
- The box you're attempting to add already exists. Remove it b
- The box you're attempting to add has no available version th
- The checksum of the downloaded box did not match the expecte
- This Vagrant environment has specified that it requires the
- A URL to a Vagrant Cloud server is not set, so boxes cannot
AI-assisted analysis of hashicorp/vagrant@35f3160f4a (2026-08-21).
Data as JSON: /api/errors/371e5fec64289edd.
Report an issue: GitHub.