hashicorp/vagrant · error · Vagrant::Errors::BoxUpdateNoMetadata
The box '%{name}' is not a versioned box. The box was added
Error message
The box '%{name}' is not a versioned box. The box was added directly instead of from a box catalog. Vagrant can only check the versions of boxes that were added from a catalog such as from the public Vagrant Server. What it means
BoxUpdateNoMetadata is raised by Box#has_update? (lib/vagrant/box.rb:191) when @metadata_url is nil, meaning the box was added from a bare .box file rather than from a versioned catalog. Only boxes with a catalog metadata URL carry version information, so update checks are impossible for them.
Source
Thrown at lib/vagrant/box.rb:191
message: e.extra_data[:message]
ensure
tf.unlink if tf
end
# Checks if the box has an update and returns the metadata, version,
# and provider. If the box doesn't have an update that satisfies the
# constraints, it will return nil.
#
# This will potentially make a network call if it has to load the
# metadata from the network.
#
# @param [String] version Version constraints the update must
# satisfy. If nil, the version constrain defaults to being a
# larger version than this box.
# @return [Array]
def has_update?(version=nil, download_options: {})
if !@metadata_url
raise Errors::BoxUpdateNoMetadata, name: @name
end
if download_options.delete(:automatic_check) && !automatic_update_check_allowed?
@logger.info("Skipping box update check")
return
end
version += ", " if version
version ||= ""
version += "> #{@version}"
md = self.load_metadata(download_options)
newer = md.version(version, provider: @provider, architecture: @architecture)
return nil if newer == nil || !md.compatible_version_update?(@version, newer.version, provider: @provider, architecture: @architecture)
[md, newer, newer.provider(@provider, @architecture)]
end
View on GitHub (pinned to 35f3160f4a)
Solutions
- Re-add the box from a catalog (host a metadata.json with versions/providers and run 'vagrant box add <metadata-url> --name x') so version tracking works
- If updates are not needed, stop invoking outdated/update checks on this box and set config.vm.box_check_update = false
- Remove the ambiguity: keep versioned boxes in Vagrant Cloud or an internal catalog and reference them by name, not by .box path
Example fix
# before: unversioned add vagrant box add ./mybox_virtualbox.box --name corp/mybox # after: versioned catalog add vagrant box add https://boxes.corp/mybox/metadata.json --name corp/mybox
Defensive patterns
Strategy: validation
Validate before calling
skip_update_check = box.metadata_url.nil? # only catalog boxes are versioned box.has_update? unless skip_update_check
Prevention
- Distribute internal boxes via a catalog metadata.json URL, never a bare .box path, if you need update checks
- Turn off box_check_update in Vagrantfiles that use local .box artifacts
When it happens
Trigger: Calling box.has_update? (or running 'vagrant box outdated' / 'vagrant box update' / Vagrantfile box_check_update) on a box added via 'vagrant box add /path/file.box --name x' — such boxes have no metadata_url, so the guard at the top of has_update? raises immediately.
Common situations: Teams distributing internal .box files directly instead of hosting a catalog metadata.json; CI images added offline; users expecting 'vagrant box outdated' to work on locally-built boxes.
Related errors
- The metadata for the box was malformed. The exact error is s
- A version of the box you're loading is formatted in a way th
- You requested to remove the box '%{name}'. This box has mult
- cloud-init is not found. Please ensure that cloud-init is in
- The "metadata.json" file for the box '%{name}' was not found
AI-assisted analysis of hashicorp/vagrant@35f3160f4a (2026-08-21).
Data as JSON: /api/errors/b4ed4d7c4e8a0eb8.
Report an issue: GitHub.