puppetlabs/puppet · error · Puppet::Error

Invalid option use_node for a remote request

Error message

Invalid option use_node for a remote request

What it means

node_from_request allows a local caller to supply options[:use_node] — a pre-built Puppet::Node object to compile instead of doing a lookup (used by local compile tooling and load testing). For remote (REST) requests this option is rejected with Puppet::Error, because accepting an arbitrary node object over HTTP would bypass node lookup and the authorization rules that depend on it.

Source

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

        Puppet.log_exception(detail, message)
        raise Puppet::Error, message, detail.backtrace
      end

      # Add any external data to the node.
      if node
        add_node_data(node)
      end
      node
    end
  end

  # Extract the node from the request, or use the request
  # to find the node.
  def node_from_request(facts, request)
    node = request.options[:use_node]
    if node
      if request.remote?
        raise Puppet::Error, _("Invalid option use_node for a remote request")
      else
        return node
      end
    end

    # We rely on our authorization system to determine whether the connected
    # node is allowed to compile the catalog's node referenced by key.
    # By default the REST authorization system makes sure only the connected node
    # can compile his catalog.
    # This allows for instance monitoring systems or puppet-load to check several
    # node's catalog with only one certificate and a modification to auth.conf
    # If no key is provided we can only compile the currently connected node.
    name = request.key || request.node
    node = find_node(name, request.environment, request.options[:transaction_uuid], request.options[:configured_environment], facts)
    if node
      return node
    end

View on GitHub (pinned to e227c27540)

Solutions

  1. Drop use_node from options when the request crosses the wire; remote callers must let the server resolve the node by key/certname
  2. For load testing with pre-built nodes, run the compile locally on the master instead of via REST
  3. Validate on the client side: raise before sending if the call is remote and options include :use_node

Example fix

# before (ruby, remote call)
opts = { use_node: prebuilt_node }
Puppet::Resource::Catalog.indirection.find(name, opts)  # remote => Puppet::Error

# after
opts = { transaction_uuid: SecureRandom.uuid }
Puppet::Resource::Catalog.indirection.find(name, opts)  # server resolves the node
Defensive patterns

Strategy: validation

Validate before calling

# ruby
opts.delete(:use_node) if remote?
raise Puppet::Error, 'use_node is local-only' if remote? && opts.key?(:use_node)

Type guard

def local_request?(request)
  !request.remote?
end

Try / catch

begin
  compiler.find(request)
rescue Puppet::Error => e
  raise unless e.message.include?('use_node')
  request.options.delete(:use_node)
  retry
end

Prevention

When it happens

Trigger: An HTTP client sends a catalog request whose options include use_node; tooling built around the local compile API pointed at the REST endpoint instead of running on the master; a custom face forwarding local-style option hashes to a remote server.

Common situations: puppet-load or benchmark harnesses misconfigured to drive the REST terminus while still passing use_node; custom orchestration reusing one options hash between local and remote calls.

Related errors


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