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

An error occurred while executing multiple actions in parall

Error message

An error occurred while executing multiple actions in parallel. Any errors that occurred are shown below.

%{message}

What it means

BatchMultiError is raised at the end of BatchAction#run (lib/vagrant/batch_action.rb:167) when one or more machine-action threads recorded an error. It aggregates the per-machine failure messages (joined with blank lines) collected from thread[:error] / unexpected exceptions, so the body lists each machine that failed and why.

Source

Thrown at lib/vagrant/batch_action.rb:167

          if !thread[:error].is_a?(Errors::VagrantError)
            e       = thread[:error]
            message = e.message
            message += "\n"
            message += "\n#{e.backtrace.join("\n")}"

            errors << I18n.t("vagrant.general.batch_unexpected_error",
                             machine: thread[:machine].name,
                             message: message)
          else
            errors << I18n.t("vagrant.general.batch_vagrant_error",
                             machine: thread[:machine].name,
                             message: thread[:error].message)
          end
        end
      end

      if !errors.empty?
        raise Errors::BatchMultiError, message: errors.join("\n\n")
      end

      # Check if any threads set an exit code and exit if found. If
      # multiple threads have exit code values set, the first encountered
      # will be the value used.
      threads.each do |thread|
        if thread[:exit_code]
          @logger.debug("Found exit code set within batch action thread. Exiting")
          Process.exit!(thread[:exit_code])
        end
      end
    end
  end
end

View on GitHub (pinned to 35f3160f4a)

Solutions

  1. Read the per-machine sections inside the error body: each block names the machine and its real message; fix that root error first
  2. Re-run only the failed machines: 'vagrant up <machine-name>' to iterate faster
  3. Disable parallelism to get linear, uncluttered output: VAGRANT_NO_PARALLEL=1 vagrant up
  4. Re-run with '--debug' (DEBUG=1) for a stack trace of the failing thread

Example fix

# before
vagrant up

# after (isolate the failing machine, sequential output)
VAGRANT_NO_PARALLEL=1 vagrant up web
Defensive patterns

Strategy: try-catch

Try / catch

begin
  Vagrant::BatchAction.new(true).tap do |b|
    machines.each { |m| b.custom(m) { |machine| machine.action(:up) } }
    b.run
  end
rescue Vagrant::Errors::BatchMultiError => e
  # e.message body: one block per failed machine
  failed = e.message.split("\n\n")
  failed.each { |blk| report(blk) }
end

Prevention

When it happens

Trigger: Running a multi-machine action in parallel ('vagrant up' with parallel enabled, e.g. VirtualBox provider) where at least one machine's action raises a VagrantError or an unexpected exception; after all threads join, errors is non-empty and the combined error is raised. A thread setting thread[:exit_code] can also cause Process.exit! right after.

Common situations: 'vagrant up' on a Vagrantfile with several VMs where one has a bad box or provider error; parallel provision where one node cannot reach the network; partial infra failures hidden behind one combined message.

Related errors


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