{"record":{"id":"de70c4d6fcfb30d1","repo":"puppetlabs/puppet","slug":"invalid-option-use-node-for-a-remote-request","errorCode":null,"errorMessage":"Invalid option use_node for a remote request","messagePattern":"Invalid option use_node for a remote request","errorType":"validation","errorClass":"Puppet::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/indirector/catalog/compiler.rb","lineNumber":403,"sourceCode":"        Puppet.log_exception(detail, message)\n        raise Puppet::Error, message, detail.backtrace\n      end\n\n      # Add any external data to the node.\n      if node\n        add_node_data(node)\n      end\n      node\n    end\n  end\n\n  # Extract the node from the request, or use the request\n  # to find the node.\n  def node_from_request(facts, request)\n    node = request.options[:use_node]\n    if node\n      if request.remote?\n        raise Puppet::Error, _(\"Invalid option use_node for a remote request\")\n      else\n        return node\n      end\n    end\n\n    # We rely on our authorization system to determine whether the connected\n    # node is allowed to compile the catalog's node referenced by key.\n    # By default the REST authorization system makes sure only the connected node\n    # can compile his catalog.\n    # This allows for instance monitoring systems or puppet-load to check several\n    # node's catalog with only one certificate and a modification to auth.conf\n    # If no key is provided we can only compile the currently connected node.\n    name = request.key || request.node\n    node = find_node(name, request.environment, request.options[:transaction_uuid], request.options[:configured_environment], facts)\n    if node\n      return node\n    end\n","sourceCodeStart":385,"sourceCodeEnd":421,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/indirector/catalog/compiler.rb#L385-L421","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Drop use_node from options when the request crosses the wire; remote callers must let the server resolve the node by key/certname","For load testing with pre-built nodes, run the compile locally on the master instead of via REST","Validate on the client side: raise before sending if the call is remote and options include :use_node"],"exampleFix":"# before (ruby, remote call)\nopts = { use_node: prebuilt_node }\nPuppet::Resource::Catalog.indirection.find(name, opts)  # remote => Puppet::Error\n\n# after\nopts = { transaction_uuid: SecureRandom.uuid }\nPuppet::Resource::Catalog.indirection.find(name, opts)  # server resolves the node","handlingStrategy":"validation","validationCode":"# ruby\nopts.delete(:use_node) if remote?\nraise Puppet::Error, 'use_node is local-only' if remote? && opts.key?(:use_node)","typeGuard":"def local_request?(request)\n  !request.remote?\nend","tryCatchPattern":"begin\n  compiler.find(request)\nrescue Puppet::Error => e\n  raise unless e.message.include?('use_node')\n  request.options.delete(:use_node)\n  retry\nend","preventionTips":["Treat use_node as a local-only escape hatch; never serialize it over HTTP","Maintain separate option hashes for local compile tooling and REST clients","Assert !request.remote? in any helper that injects use_node"],"tags":["puppet-compiler","remote-request","security","invalid-option"],"backgroundTag":"invalid-request-option","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}