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

Could not run remote script on %{machine_name} because its s

Error message

Could not run remote script on %{machine_name} because its state is %{state}

What it means

A `run_remote` trigger (executes inside the guest) fired while the target machine's state was not :running (lib/vagrant/plugin/v2/trigger.rb:312). This path means the machine object exists but is in another state (:poweroff, :suspended, etc.); a machine that does not exist at all raises TriggersGuestNotExist instead. With on_error :halt the error is raised; otherwise Vagrant warns and continues.

Source

Thrown at lib/vagrant/plugin/v2/trigger.rb:312

          end
        end

        # Runs a script on the guest
        #
        # @param [ShellProvisioner/Config] config A Shell provisioner config
        def run_remote(config, on_error, exit_codes)
          if !@machine
            # machine doesn't even exist.
            if on_error == :halt
              raise Errors::TriggersGuestNotExist
            else
              @ui.warn(I18n.t("vagrant.errors.triggers_guest_not_exist"))
              @ui.warn(I18n.t("vagrant.trigger.on_error_continue"))
              return
            end
          elsif @machine.state.id != :running
            if on_error == :halt
              raise Errors::TriggersGuestNotRunning,
                machine_name: @machine.name,
                state: @machine.state.id
            else
              @machine.ui.error(I18n.t("vagrant.errors.triggers_guest_not_running",
                                        machine_name: @machine.name,
                                        state: @machine.state.id))
              @machine.ui.warn(I18n.t("vagrant.trigger.on_error_continue"))
              return
            end
          end

          prov = VagrantPlugins::Shell::Provisioner.new(@machine, config)

          begin
            prov.provision
          rescue => e
            @machine.ui.error(I18n.t("vagrant.errors.triggers_run_fail"))

View on GitHub (pinned to 35f3160f4a)

Solutions

  1. Move the run_remote trigger to a stage where the guest is guaranteed running: trigger.before :halt, or trigger.after :up / after :provision
  2. Use host-side `t.run` instead of `t.run_remote` for teardown stages (after halt/destroy)
  3. Set t.on_error = :continue if the trigger is opportunistic and failure is tolerable
  4. Verify current state with `vagrant status <machine>` before re-running

Example fix

# before
trigger.after :halt do |t|
  t.run_remote = { inline: "echo bye" }  # guest is powered off here
end

# after
trigger.before :halt do |t|
  t.run_remote = { inline: "echo bye" }  # guest still running
end
Defensive patterns

Strategy: validation

Validate before calling

machine = env.machine(:web, :virtualbox)
abort "guest not running (state: #{machine.state.id})" unless machine.state.id == :running

Try / catch

begin
  env.cli(:halt)
rescue Vagrant::Errors::TriggersGuestNotRunning => e
  d = e.extra_data # {machine_name:, state:}
  warn "#{d[:machine_name]} was #{d[:state]} — move the run_remote trigger to a stage where the guest runs"
end

Prevention

When it happens

Trigger: A Vagrantfile like `trigger.after :halt do |t| t.run_remote = {inline: "..."} end` — after halting, the state is :poweroff so the remote script cannot run; similarly after :suspend, or an :up trigger firing in a flow where the guest is not yet running.

Common situations: Copy-pasted trigger blocks attached to the wrong command/stage; expecting run_remote to work during teardown; the guest crashing or being halted externally before the trigger fires.

Related errors


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