{"record":{"id":"89b8f4ff15664d3a","repo":"puppetlabs/puppet","slug":"you-must-set-the-external-nodes-parameter-to-use","errorCode":null,"errorMessage":"You must set the 'external_nodes' parameter to use the external node terminus","messagePattern":"You must set the 'external_nodes' parameter to use the external node terminus","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/indirector/node/exec.rb","lineNumber":13,"sourceCode":"# frozen_string_literal: true\n\nrequire_relative '../../../puppet/node'\nrequire_relative '../../../puppet/indirector/exec'\n\nclass Puppet::Node::Exec < Puppet::Indirector::Exec\n  desc \"Call an external program to get node information.  See\n  the [External Nodes](https://puppet.com/docs/puppet/latest/lang_write_functions_in_puppet.html) page for more information.\"\n  include Puppet::Util\n\n  def command\n    command = Puppet[:external_nodes]\n    raise ArgumentError, _(\"You must set the 'external_nodes' parameter to use the external node terminus\") unless command != _(\"none\")\n\n    command.split\n  end\n\n  # Look for external node definitions.\n  def find(request)\n    output = super or return nil\n\n    # Translate the output to ruby.\n    result = translate(request.key, output)\n\n    facts = request.options[:facts].is_a?(Puppet::Node::Facts) ? request.options[:facts] : nil\n\n    # Set the requested environment if it wasn't overridden\n    # If we don't do this it gets set to the local default\n    result[:environment] ||= request.environment\n\n    create_node(request.key, result, facts)","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/indirector/node/exec.rb#L1-L31","documentation":"The exec node terminus (node_terminus = exec) builds its command from the external_nodes setting, which defaults to the literal string \"none\". The command accessor explicitly refuses to run when the setting still equals \"none\", raising ArgumentError before any external node script is invoked. This is a configuration guard: the terminus is selected but the script it needs was never configured.","triggerScenarios":"Setting node_terminus = exec in puppet.conf without also setting external_nodes; or explicitly leaving external_nodes = none while expecting node facts to come from an ENC. Triggered the moment the master attempts to resolve a node (Puppet::Node.indirection.find during catalog compilation).","commonSituations":"Copy-pasted puppet.conf fragments that set node_terminus but omit external_nodes; disabling an ENC by resetting external_nodes to none while forgetting to revert node_terminus to plain; upgrading from legacy ENC docs without setting the script path.","solutions":["Set the ENC script path in the [master] section: puppet config set external_nodes /usr/local/bin/enc.sh --section master","Ensure the script is executable (chmod +x) and returns YAML on stdout","If you no longer want an ENC, switch back to the default: puppet config set node_terminus plain --section master","Restart puppetserver after changing these settings so the JRuby pool picks them up"],"exampleFix":"# before (puppet.conf on master)\n[master]\n  node_terminus = exec\n# external_nodes unset -> defaults to 'none'\n# => ArgumentError: You must set the 'external_nodes' parameter to use the external node terminus\n\n# after\n[master]\n  node_terminus = exec\n  external_nodes = /etc/puppetlabs/puppet/enc.sh","handlingStrategy":"validation","validationCode":"if Puppet[:node_terminus] == 'exec' && Puppet[:external_nodes] == 'none'\n  raise Puppet::Error, 'node_terminus=exec requires external_nodes to be set'\nend","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set external_nodes and node_terminus together in the same puppet.conf edit","Add a pre-flight config check (puppet config print external_nodes) to ENC onboarding runbooks","Test with one node before rolling the setting fleet-wide"],"tags":["puppet","external-nodes","enc","configuration","node-terminus"],"backgroundTag":"missing-configuration","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}