hashicorp/vagrant · error · Vagrant::Errors::TriggersBadExitCodes
A script exited with an unacceptable exit code %{code}.
Error message
A script exited with an unacceptable exit code %{code}. What it means
A trigger's `run` script finished with an exit code not in the trigger's allowed exit_codes list (default [0]), so run_script raised TriggersBadExitCodes (lib/vagrant/plugin/v2/trigger.rb:280). With the default `on_error: :halt` the error is re-raised after the script's output, aborting the vagrant command; with `on_error: :continue` Vagrant logs the failure and continues instead. %{code} is the script's actual exit status.
Source
Thrown at lib/vagrant/plugin/v2/trigger.rb:280
else
exec_method = Vagrant::Util::PowerShell.method(:execute)
end
end
begin
result = exec_method.call(*cmd, :notify => [:stdout, :stderr]) do |type,data|
options = {}
case type
when :stdout
options[:color] = :green if !config.keep_color
when :stderr
options[:color] = :red if !config.keep_color
end
@ui.detail(data, **options)
end
if !exit_codes.include?(result.exit_code)
raise Errors::TriggersBadExitCodes,
code: result.exit_code
end
rescue => e
@ui.error(I18n.t("vagrant.errors.triggers_run_fail"))
@ui.error(e.message)
if on_error == :halt
@logger.debug("Trigger run encountered an error. Halting on error...")
raise e
else
@logger.debug("Trigger run encountered an error. Continuing on anyway...")
@ui.warn(I18n.t("vagrant.trigger.on_error_continue"))
end
end
end
# Runs a script on the guest
#View on GitHub (pinned to 35f3160f4a)
Solutions
- Run the script manually the way Vagrant does (bash -c from the project root) and fix whatever makes it exit non-zero
- If the non-zero code is expected, whitelist it on the trigger: t.exit_codes = [0, 1]
- If failure is acceptable for this workflow, set t.on_error = :continue
- Debug with VAGRANT_LOG=debug to see the exact executed command and its output
Example fix
# before
trigger.after :up do |t|
t.run = { inline: "./check.sh" } # check.sh exits 1 on warnings
end
# after
trigger.after :up do |t|
t.run = { inline: "./check.sh" }
t.exit_codes = [0, 1] # 1 means warning, not failure
end Defensive patterns
Strategy: validation
Validate before calling
ok = system("bash", "-c", "./check.sh", out: File::NULL, err: File::NULL)
code = $?.exitstatus
abort "trigger script exits #{code}; whitelist it via exit_codes or fix the script" unless code.zero? Try / catch
begin
env.cli(:up)
rescue Vagrant::Errors::TriggersBadExitCodes => e
warn "trigger script failed with exit code #{e.extra_data[:code]}"
end Prevention
- Make trigger scripts exit 0 on success; report warnings on stderr instead of via exit codes
- chmod +x local scripts and use paths relative to the project root
- Whitelist every intentional non-zero code with t.exit_codes = [0, N]
- Decide explicitly per trigger whether on_error should :halt or :continue
When it happens
Trigger: A Vagrantfile trigger like `trigger.after :up do |t| t.run = {inline: "./script.sh"} end` where script.sh exits 1 — including the shell's 127 for a missing script and 126 for a non-executable file — and the code is not whitelisted via t.exit_codes.
Common situations: Scripts that use non-zero exits for warnings (grep-style); forgetting chmod +x; paths assumed wrong relative to the project root; scripts depending on env vars absent in the trigger context; Windows batch exit codes.
Related errors
- The incorrect stage was given to the trigger plugin: Guest:
- Could not run remote script on %{machine_name} because its s
- There was an error parsing the Vagrantfile: No config was gi
- A Docker command executed by Vagrant didn't complete success
- A Docker command executed by Vagrant didn't complete success
AI-assisted analysis of hashicorp/vagrant@35f3160f4a (2026-08-21).
Data as JSON: /api/errors/e682bcf2829d7d3f.
Report an issue: GitHub.