puppetlabs/puppet · error · RuntimeError
Could not call '%{method}' on '%{indirection}': %{detail}
Error message
Could not call '%{method}' on '%{indirection}': %{detail} What it means
Puppet::Indirector::Face#call_indirection_method is the funnel behind every 'puppet <indirection> <action>' CLI subcommand (facts find, certificate sign, node find, ...). Any exception from the underlying terminus is logged with backtrace and re-raised as RuntimeError 'Could not call <method> on <indirection>: <detail>' — it is a wrapper, and the actionable cause is always the detail text and the logged exception.
Source
Thrown at lib/puppet/indirector/face.rb:53
Puppet::Indirector::Indirection.instances.collect(&:to_s).sort
end
def self.terminus_classes(indirection)
Puppet::Indirector::Terminus.terminus_classes(indirection.to_sym).collect(&:to_s).sort
end
def call_indirection_method(method, key, options)
begin
if method == :save
# key is really the instance to save
result = indirection.__send__(method, key, nil, options)
else
result = indirection.__send__(method, key, options)
end
rescue => detail
message = _("Could not call '%{method}' on '%{indirection}': %{detail}") % { method: method, indirection: indirection_name, detail: detail }
Puppet.log_exception(detail, message)
raise RuntimeError, message, detail.backtrace
end
result
end
action :destroy do
summary _("Delete an object.")
arguments _("<key>")
when_invoked { |key, _options| call_indirection_method :destroy, key, {} }
end
action :find do
summary _("Retrieve an object by name.")
arguments _("[<key>]")
when_invoked do |*args|
# Default the key to Puppet[:certname] if none is supplied
if args.length == 1
key = Puppet[:certname]View on GitHub (pinned to e227c27540)
Solutions
- Run the same command with --trace (and --debug) to get the original backtrace logged when the wrapper fired
- Fix the named detail cause: terminus setting, connectivity, permissions, or SSL state as indicated
- Reproduce outside the face by calling the indirection in Ruby to isolate face-specific option bugs
Example fix
# before $ puppet facts find node1.example.com # Error: Could not call 'find' on 'facts': ... # after $ puppet facts find node1.example.com --trace --debug # read the original exception; fix facts_terminus/server, then rerun
Defensive patterns
Strategy: try-catch
Validate before calling
# ruby # pre-flight the terminus before invoking the face if opts[:terminus] == 'rest' require 'socket' TCPSocket.new(Puppet[:server], Puppet[:serverport]).close end Puppet::Face[:facts, :current].find(name)
Type guard
def indirection_callable?(face_name, method) Puppet::Face[face_name, :current].respond_to?(method) end
Try / catch
begin
face.call_indirection_method(method, key, options)
rescue RuntimeError => e
raise unless e.message.start_with?('Could not call')
Puppet.err(e.message) # wrapper text names the method and indirection
nil
end Prevention
- Always add --trace on face failures; the wrapper logs the original backtrace
- Run face commands as the correct user with valid terminus settings
- In scripts needing typed exceptions, call the indirection API directly instead of the face wrapper
When it happens
Trigger: puppet facts find node1 --terminus rest when the server is unreachable (wraps the network error); certificate generation with broken SSL state; any terminus rejecting the option combination the face forwarded.
Common situations: CLI usage against a misconfigured terminus (facts_terminus=rest with a wrong server setting); running face commands as the wrong user so file or SSL access fails; debugging only from the wrapper message instead of the --trace output.
Related errors
- Failed when searching for node %{name}: %{detail}
- The legacy subcommand '%{sub_command}' does not support supp
- Facts but no fact format provided for %{request}
- Find %{uri} resulted in 404 with the message: %{body}
- Find %{uri} resulted in 404 with the message: %{body}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/87080024e0cd9b17.
Report an issue: GitHub.