hashicorp/vagrant · warning · Vagrant::Errors::BoxAddMetadataMultiURL

Multiple URLs for a box can't be specified when adding versi

Error message

Multiple URLs for a box can't be specified when adding
versioned boxes. Please specify a single URL to the box
metadata (JSON) information. The full list of URLs you
specified is shown below:

%{urls}

What it means

DockerProvisioner::Installer#ensure_installed (installer.rb:14-19) first asks `@machine.guest.capability?(:docker_installed)`. When the detected guest plugin does not register that capability, Vagrant warns "Vagrant doesn't support detecting whether Docker is installed for the guest OS running in the machine. Vagrant will assume it is installed and attempt to continue." and returns false — the install step is skipped entirely. Later docker provisioner actions (pull/build/run) then only work if Docker really is present in the box.

Source

Thrown at lib/vagrant/action/builtin/box_add.rb:152

            if is_error
              raise Errors::BoxAddShortNotFound,
                error: is_error.extra_data[:message],
                name: env[:box_url],
                url: url
            end
          end

          is_error = is_metadata_results.find do |b|
            b.is_a?(Errors::DownloaderError)
          end
          if is_error
            raise Errors::BoxMetadataDownloadError,  
              message: is_error.extra_data[:message]
          end

          is_metadata = is_metadata_results.any? { |b| b === true }
          if is_metadata && url.length > 1
            raise Errors::BoxAddMetadataMultiURL,
              urls: url.join(", ")
          end

          if is_metadata
            url = [url.first, authed_urls.first]
            add_from_metadata(url, env, expanded)
          else
            add_direct(authed_urls, env)
          end

          @app.call(env)
        end

        # Adds a box file directly (no metadata component, versioning,
        # etc.)
        #
        # @param [Array<String>] urls
        # @param [Hash] env

View on GitHub (pinned to 35f3160f4a)

Solutions

  1. Verify Docker is actually in the guest: `vagrant ssh -c 'command -v docker && docker --version'`.
  2. If absent, install it yourself before the docker provisioner: a shell provisioner running the get.docker.com script or `apt-get install docker.io`.
  3. Switch to a base box with supported guest detection (e.g. bento/ubuntu-*, roboxes) so capability?(:docker_installed) returns true.
  4. Upgrade Vagrant — newer releases add docker_installed capabilities for more guests.

Example fix

# Vagrantfile — before
config.vm.provision "docker" do |d|
  d.pull_image "nginx"
end

# after (guest without docker_installed capability: install explicitly)
config.vm.provision "shell", inline: "command -v docker >/dev/null || (curl -fsSL https://get.docker.com | sh)"
config.vm.provision "docker" do |d|
  d.pull_image "nginx"
end
Defensive patterns

Strategy: validation

Validate before calling

# Pre-flight: does the guest expose docker and is it actually installed?
vagrant ssh -c 'command -v docker && docker --version'

Type guard

# Where you hold a machine object (plugin/pry context)
def docker_verifiable?(machine)
  machine.guest.capability?(:docker_installed)
end

Prevention

When it happens

Trigger: Using the docker provisioner (`config.vm.provision "docker"`) on a base box whose guest OS is not mapped to a guest plugin implementing docker_installed — niche, custom, or very new distros, or boxes whose OS detection files confuse Vagrant's guest detection.

Common situations: Hand-rolled Packer/minimal boxes lacking the distro markers Vagrant detects; a new Ubuntu/Debian/Fedora point release before guest plugin updates; the result that Docker is genuinely absent, so `vagrant up` later fails inside docker pull/build with 'docker: command not found' style errors.

Related errors


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