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
- Move the run_remote trigger to a stage where the guest is guaranteed running: trigger.before :halt, or trigger.after :up / after :provision
- Use host-side `t.run` instead of `t.run_remote` for teardown stages (after halt/destroy)
- Set t.on_error = :continue if the trigger is opportunistic and failure is tolerable
- 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
- Pair run_remote only with commands that leave the guest running (after :up, before :halt, after :provision)
- Use host-side `run` for teardown stages (after halt/destroy)
- Smoke-test each trigger stage against `vagrant status` before committing the Vagrantfile
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
- Could not run remote script on guest because it does not exi
- The clone environment hasn't been created yet. To clone from
- The provider for this Vagrant-managed machine is reporting t
- The provider for this Vagrant-managed machine is reporting t
- The incorrect stage was given to the trigger plugin: Guest:
AI-assisted analysis of hashicorp/vagrant@35f3160f4a (2026-08-21).
Data as JSON: /api/errors/9bd8427923b24847.
Report an issue: GitHub.