puppetlabs/puppet · error · ArgumentError

Facts but no fact format provided for %{request}

Error message

Facts but no fact format provided for %{request}

What it means

In the catalog compiler terminus, extract_facts_from_request pulls client facts out of an indirector request. If request.options[:facts] is present but request.options[:facts_format] is nil, the server cannot know how to deserialize the payload and raises ArgumentError. Requests without facts return early and are unaffected.

Source

Thrown at lib/puppet/indirector/catalog/compiler.rb:30

class Puppet::Resource::Catalog::Compiler < Puppet::Indirector::Code
  desc "Compiles catalogs on demand using Puppet's compiler."

  include Puppet::Util
  include Puppet::Util::Checksums

  attr_accessor :code

  # @param request [Puppet::Indirector::Request] an indirection request
  #   (possibly) containing facts
  # @return [Puppet::Node::Facts] facts object corresponding to facts in request
  def extract_facts_from_request(request)
    text_facts = request.options[:facts]
    return unless text_facts

    format = request.options[:facts_format]
    unless format
      raise ArgumentError, _("Facts but no fact format provided for %{request}") % { request: request.key }
    end

    Puppet::Util::Profiler.profile(_("Found facts"), [:compiler, :find_facts]) do
      facts = text_facts.is_a?(Puppet::Node::Facts) ? text_facts :
                                                      convert_wire_facts(text_facts, format)

      unless facts.name == request.key
        raise Puppet::Error, _("Catalog for %{request} was requested with fact definition for the wrong node (%{fact_name}).") % { request: request.key.inspect, fact_name: facts.name.inspect }
      end

      return facts
    end
  end

  def save_facts_from_request(facts, request)
    Puppet::Node::Facts.indirection.save(facts, nil,
                                         :environment => request.environment,
                                         :transaction_uuid => request.options[:transaction_uuid])

View on GitHub (pinned to e227c27540)

Solutions

  1. Always set both options together: facts: serialized_facts, facts_format: 'application/json' (or 'pson' for old agents)
  2. Centralize request construction in a helper that enforces the pairing rather than building options hashes ad hoc
  3. When facts are not needed, omit :facts entirely so the early return path is taken

Example fix

# before (ruby)
Puppet::Resource::Catalog.indirection.find(
  'node1.example.com',
  facts: facts_json)  # => ArgumentError: Facts but no fact format provided

# after
Puppet::Resource::Catalog.indirection.find(
  'node1.example.com',
  facts: facts_json,
  facts_format: 'application/json')
Defensive patterns

Strategy: validation

Validate before calling

# ruby
opts = {}
if serialized_facts
  opts[:facts] = serialized_facts
  opts[:facts_format] = 'application/json'  # never one without the other
end
Puppet::Resource::Catalog.indirection.find(name, opts)

Type guard

def facts_options_complete?(opts)
  opts[:facts].nil? || !opts[:facts_format].nil?
end

Try / catch

begin
  Puppet::Resource::Catalog.indirection.find(name, opts)
rescue ArgumentError => e
  raise unless e.message.include?('fact format')
  opts = opts.merge(facts_format: 'application/json')
  retry
end

Prevention

When it happens

Trigger: Calling Puppet::Resource::Catalog.indirection.find(key, facts: serialized, ...) without facts_format; building a Puppet::Indirector::Request by hand for testing or tooling and setting :facts but not :facts_format; a custom face or terminus that forwards only one of the two options.

Common situations: Legacy tooling ported from an era when PSON was assumed and the format option was optional; custom orchestration code (puppet-load style harnesses) driving the catalog indirection directly; request-munging middleware that drops the facts_format option.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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