puppetlabs/puppet · error · Puppet::Error

Failed to find %{name} via exec: %{detail}

Error message

Failed to find %{name} via exec: %{detail}

What it means

When the exec terminus actually runs the external command (with failonfail and separated stderr) and the process exits non-zero, Puppet::ExecutionFailure is caught and re-raised as Puppet::Error with the command's failure detail and the original backtrace attached. The looked-up name is appended as the command's last argument before execution, and the message embeds both the name and the stderr/failure detail.

Source

Thrown at lib/puppet/indirector/exec.rb:23

class Puppet::Indirector::Exec < Puppet::Indirector::Terminus
  # Look for external node definitions.
  def find(request)
    name = request.key
    external_command = command

    # Make sure it's an array
    raise Puppet::DevError, _("Exec commands must be an array") unless external_command.is_a?(Array)

    # Make sure it's fully qualified.
    raise ArgumentError, _("You must set the exec parameter to a fully qualified command") unless Puppet::Util.absolute_path?(external_command[0])

    # Add our name to it.
    external_command << name
    begin
      output = execute(external_command, :failonfail => true, :combine => false)
    rescue Puppet::ExecutionFailure => detail
      raise Puppet::Error, _("Failed to find %{name} via exec: %{detail}") % { name: name, detail: detail }, detail.backtrace
    end

    if output =~ /\A\s*\Z/ # all whitespace
      Puppet.debug { "Empty response for #{name} from #{self.name} terminus" }
      nil
    else
      output
    end
  end

  private

  # Proxy the execution, so it's easier to test.
  def execute(command, arguments)
    Puppet::Util::Execution.execute(command, arguments)
  end
end

View on GitHub (pinned to e227c27540)

Solutions

  1. Run the exact command by hand with a node name: /etc/puppet/node.rb node1.example.com — the output you see is the embedded detail
  2. Fix the script's crash (missing require, nil data, upstream API down) and make it exit 0 with empty output for 'not found'
  3. Check mode and shebang: chmod +x, LF line endings, interpreter exists in the service's environment

Example fix

# before: /etc/puppet/node.rb raises (missing gem)
# => Puppet::Error: Failed to find node1 via exec: ... LoadError ...

# after: vendor/install the dependency, then verify
#   /etc/puppet/node.rb node1.example.com; echo $?   # => 0
Defensive patterns

Strategy: try-catch

Validate before calling

# ruby
ok = system(Puppet[:external_nodes], name, out: File::NULL, err: File::NULL)
Puppet.warning "ENC failing for #{name}" unless ok
# run the terminus only when the pre-flight succeeds

Type guard

def enc_runnable?(name)
  system(Puppet[:external_nodes], name, out: File::NULL, err: File::NULL)
end

Try / catch

begin
  result = terminus.find(request)
rescue Puppet::Error => e
  raise unless e.message.include?('via exec')
  Puppet.err(e.message)  # message embeds the script's failure detail
  nil  # treat as node-not-found, or alert
end

Prevention

When it happens

Trigger: ENC script exits non-zero (missing gem, syntax error, upstream API failure); script not executable or with a broken shebang; permission denied on the script file.

Common situations: ENC scripts with unhandled exceptions on unusual node names; scripts depending on gems present in an interactive shell but not in the puppetserver/puppet Ruby environment; deploy pipelines shipping a script without the executable bit or with CRLF-mangled shebangs.

Related errors


AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21). Data as JSON: /api/errors/20b410fba08c7ef0. Report an issue: GitHub.