puppetlabs/puppet · error · Puppet::ExecutionFailure
output.to_s
Error message
output.to_s
What it means
Puppet::Util.execute runs a command with stdout and stderr combined under a C locale (the POSIX pipe path) and, when the failonfail option is true (the default), raises Puppet::ExecutionFailure if the exit status is non-zero. The exception message is simply the command's captured output (output.to_s). This is Puppet's standard mechanism for surfacing a failing external command.
Source
Thrown at lib/puppet/util/execution.rb:88
debug "Executing '#{command_str}'"
else
Puppet.debug { "Executing '#{command_str}'" }
end
# force the run of the command with
# the user/system locale to "C" (via environment variables LANG and LC_*)
# it enables to have non localized output for some commands and therefore
# a predictable output
english_env = ENV.to_hash.merge({ 'LANG' => 'C', 'LC_ALL' => 'C' })
output = Puppet::Util.withenv(english_env) do
# We are intentionally using 'pipe' with open to launch a process
open("| #{command_str} 2>&1") do |pipe| # rubocop:disable Security/Open
yield pipe
end
end
if failonfail && exitstatus != 0
raise Puppet::ExecutionFailure, output.to_s
end
output
end
def self.exitstatus
$CHILD_STATUS.exitstatus
end
private_class_method :exitstatus
# Default empty options for {execute}
NoOptionsSpecified = {}
# Executes the desired command, and return the status and output.
# def execute(command, options)
# @param command [Array<String>, String] the command to execute. If it is
# an Array the first element should be the executable and the rest of the
# elements should be the individual arguments to that executable.View on GitHub (pinned to e227c27540)
Solutions
- Re-run the failing command manually as the same user with the same environment; the real error is in the exception message (the combined output)
- Pass failonfail: false when a non-zero exit is expected, and branch on the returned output or exit status instead
- Rescue Puppet::ExecutionFailure explicitly at the call site and handle it
- Control the environment (PATH, locale) via the execute options so the intended command runs
Example fix
# before
Puppet::Util.execute(['/usr/sbin/useradd', '-m', 'bob'])
# => Puppet::ExecutionFailure: useradd: user 'bob' already exists
# after
begin
Puppet::Util.execute(['/usr/sbin/useradd', '-m', 'bob'])
rescue Puppet::ExecutionFailure => e
raise unless e.message.include?('already exists')
end Defensive patterns
Strategy: try-catch
Validate before calling
unless Puppet::Util.which('systemctl')
raise ArgumentError, 'systemctl not found on PATH'
end
Puppet::Util.execute(['systemctl', 'is-active', 'nginx'], failonfail: false) Try / catch
begin
Puppet::Util.execute(cmd)
rescue Puppet::ExecutionFailure => e
Puppet.err("Command failed: #{e.message}")
raise unless e.message.include?('already exists')
end Prevention
- Rescue Puppet::ExecutionFailure wherever a non-zero exit is a normal outcome
- Use failonfail: false plus explicit output checks for commands whose failure is expected
- Verify the binary exists with Puppet::Util.which before executing
When it happens
Trigger: Calling Puppet::Util.execute('systemctl reload nginx') (failonfail defaults to true) where the command exists but exits non-zero: a package manager returning 100, a validation command rejecting input, a service control command failing, and so on.
Common situations: Providers and exec-style code invoking CLI tools that fail on bad input, commands behaving differently as root versus another user, PATH differences causing a different binary to run, and callers that do not expect any non-zero exit.
Related errors
- Execution of '%{str}' returned %{exit_status}: %{output}
- Working directory %{cwd} does not exist!
- Request to Puppet Forge failed. Detail: %{detail}.
- Cannot determine basic system flavour
- No such group %{group}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/7c487c7939d36c85.
Report an issue: GitHub.