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

There was an error while downloading the metadata for this b

Error message

There was an error while downloading the metadata for this box. The error message is shown below:

%{message}

What it means

BoxMetadataDownloadError is raised in Box#load_metadata (lib/vagrant/box.rb:172) when Util::Downloader fails to fetch the box's metadata URL; the DownloaderError's message is embedded. It is the network-facing wrapper for any failure while pulling the catalog JSON that update checks and box adds depend on.

Source

Thrown at lib/vagrant/box.rb:172

      tf = Tempfile.new("vagrant-load-metadata")
      tf.close

      url = @metadata_url
      if File.file?(url) || url !~ /^[a-z0-9]+:.*$/i
        url = File.expand_path(url)
        url = Util::Platform.cygwin_windows_path(url)
        url = "file:#{url}"
      end

      opts = { headers: ["Accept: application/json"] }.merge(download_options)
      d = Util::Downloader.new(url, tf.path, opts)
      if @hook
        @hook.call(:authenticate_box_downloader, downloader: d)
      end
      d.download!
      BoxMetadata.new(File.open(tf.path, "r"), url: url)
    rescue Errors::DownloaderError => e
      raise Errors::BoxMetadataDownloadError,
        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

View on GitHub (pinned to 35f3160f4a)

Solutions

  1. Fetch the metadata URL manually (curl -i <url>) to see the actual HTTP error and share it with whoever hosts the catalog
  2. Fix network/proxy config: set HTTPS_PROXY/HTTP_PROXY, or add CA certs if TLS interception breaks the download
  3. If the URL is dead/renamed, re-add the box from the corrected catalog URL
  4. Disable unwanted automatic checks with 'vagrant box update --no-download' behavior or config.vm.box_check_update = false in the Vagrantfile

Example fix

# before (Vagrantfile)
config.vm.box_check_update = true

# after (offline/proxied environment)
config.vm.box_check_update = false
Defensive patterns

Strategy: retry

Validate before calling

require 'net/http'
uri = URI(box.metadata_url)
resp = Net::HTTP.get_response(uri)
raise "catalog unreachable: HTTP #{resp.code}" unless resp.code == '200'

Try / catch

begin
  box.has_update?
rescue Vagrant::Errors::BoxMetadataDownloadError => e
  retry_if_transient(e.message, max: 3) # re-run after backoff; abort on 4xx/proxy errors
end

Prevention

When it happens

Trigger: load_metadata builds a Util::Downloader for @metadata_url (with Accept: application/json and any hook-based authentication) and calls d.download!; any Errors::DownloaderError (DNS failure, 404, 5xx, TLS error, proxy refusal) is re-raised as BoxMetadataDownloadError. Hit via 'vagrant box outdated', 'vagrant box update', auto-update checks, or adding from a catalog URL.

Common situations: Corporate proxy/MITM filtering blocking app.vagrantup.com or a private Atlas/Vagrant Cloud URL; mistyped or dead metadata_url in internally-hosted catalogs; expired signed URLs; offline machines running update checks.

Related errors


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