puppetlabs/puppet · error · Puppet::Error

Could not retrieve local facts: %{detail}

Error message

Could not retrieve local facts: %{detail}

What it means

Wrapping error from `Puppet::Configurer::FactHandler#find_facts`: collecting local facts via `Puppet::Node::Facts.indirection.find` raised an unexpected Exception (SystemExit and NoMemoryError are explicitly re-raised untouched). The original exception is logged through `Puppet.log_exception` and re-raised as Puppet::Error with the original backtrace attached, so `%{detail}` is the text of the underlying Facter failure.

Source

Thrown at lib/puppet/configurer/fact_handler.rb:28

# easier to test.
module Puppet::Configurer::FactHandler
  def find_facts
    # This works because puppet agent configures Facts to use 'facter' for
    # finding facts and the 'rest' terminus for caching them.  Thus, we'll
    # compile them and then "cache" them on the server.

    facts = Puppet::Node::Facts.indirection.find(Puppet[:node_name_value], :environment => Puppet::Node::Environment.remote(@environment))
    unless Puppet[:node_name_fact].empty?
      Puppet[:node_name_value] = facts.values[Puppet[:node_name_fact]]
      facts.name = Puppet[:node_name_value]
    end
    facts
  rescue SystemExit, NoMemoryError
    raise
  rescue Exception => detail
    message = _("Could not retrieve local facts: %{detail}") % { detail: detail }
    Puppet.log_exception(detail, message)
    raise Puppet::Error, message, detail.backtrace
  end

  def facts_for_uploading
    encode_facts(find_facts)
  end

  def encode_facts(facts)
    # facts = find_facts

    # NOTE: :facts specified as parameters are URI encoded here,
    # then  encoded for a second time depending on their length:
    #
    # <= 1024 characters sent via query string of a HTTP GET, additionally query string encoded
    # > 1024 characters sent in POST data, additionally x-www-form-urlencoded
    # so it's only important that encoding method here return original values
    # correctly when CGI.unescape called against it (in compiler code)
    if Puppet[:preferred_serialization_format] == "pson"
      { :facts_format => :pson, :facts => Puppet::Util.uri_query_encode(facts.render(:pson)) }

View on GitHub (pinned to e227c27540)

Solutions

  1. Reproduce outside Puppet: run `facter -p` (custom facts) and `facter` — the same failure surfaces with its backtrace
  2. Fix or harden the failing custom/external fact (rescue inside setcode, check File.exist? before reads)
  3. Verify version compatibility (e.g. Puppet 7 expects Facter 4.x) and consistent gem/native installs
  4. Run `puppet agent -t --trace`: the wrapped original backtrace shows exactly which fact failed

Example fix

# before: custom fact crashes when file is absent
Facter.add(:app_version) do
  setcode { File.read('/etc/app/version').strip }  # Errno::ENOENT
end
# after
Facter.add(:app_version) do
  setcode do
    File.exist?('/etc/app/version') ? File.read('/etc/app/version').strip : nil
  end
end
Defensive patterns

Strategy: try-catch

Validate before calling

# smoke-test fact resolution before an agent run
facts = Facter.to_hash
abort 'fact resolution failed' if facts.nil? || facts.empty?

Try / catch

begin
  facts = Puppet::Node::Facts.indirection.find(Puppet[:node_name_value], environment: env)
rescue Puppet::Error => e
  # e.message is 'Could not retrieve local facts: <original>'
  # the original backtrace is attached; surface it to locate the bad fact
  $stderr.puts e.message
  warn 'run `facter -p --debug` to identify the failing custom fact'
  raise
end

Prevention

When it happens

Trigger: Any Ruby exception while Facter resolves facts on the agent: a custom fact whose setcode block raises (NoMethodError, Errno::*), an external fact script that fails, a Facter/Puppet version mismatch breaking the fact API, or a broken PATH preventing helper execution.

Common situations: Custom facts written for legacy Facter using removed APIs; external facts with a bad shebang or non-zero exit; hybrid Facter 3/4 installs after an agent upgrade; module-dropped facts using platform-specific code that fails on a new OS.

Related errors


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