puppetlabs/puppet · error · Puppet::ParseError

Could not find node statement with name 'default' or '%{name

Error message

Could not find node statement with name 'default' or '%{names}'

What it means

When the environment's code contains node statements (known_resource_types.nodes? is true), evaluate_ast_node looks for a node definition matching any of the node's names (certname, fqdn...) and falls back to node default. If neither exists it raises Puppet::ParseError listing the names tried. Note: once any node statement exists, every node must match one of them or node default.

Source

Thrown at lib/puppet/parser/compiler.rb:220

    evaluate_classes(classes_without_params, @node_scope || topscope)
  end

  # If ast nodes are enabled, then see if we can find and evaluate one.
  #
  # @api private
  def evaluate_ast_node
    krt = environment.known_resource_types
    return unless krt.nodes? # ast_nodes?

    # Now see if we can find the node.
    astnode = nil
    @node.names.each do |name|
      astnode = krt.node(name.to_s.downcase)
      break if astnode
    end

    unless astnode ||= krt.node("default")
      raise Puppet::ParseError, _("Could not find node statement with name 'default' or '%{names}'") % { names: node.names.join(", ") }
    end

    # Create a resource to model this node, and then add it to the list
    # of resources.
    resource = astnode.ensure_in_catalog(topscope)

    resource.evaluate

    @node_scope = topscope.class_scope(astnode)
  end

  # Evaluates each specified class in turn. If there are any classes that
  # can't be found, an error is raised. This method really just creates resource objects
  # that point back to the classes, and then the resources are themselves
  # evaluated later in the process.
  #
  def evaluate_classes(classes, scope, lazy_evaluate = true)
    raise Puppet::DevError, _("No source for scope passed to evaluate_classes") unless scope.source

View on GitHub (pinned to e227c27540)

Solutions

  1. Add a catch-all: node default { include baseline }
  2. Correct the node statement to match the certname (or set the agent's certname explicitly)
  3. Or remove node statements entirely and classify via ENC/group profiles

Example fix

// before
site.pp: node 'web1.example.com' { include role::web }

// after
site.pp:
node 'web1.example.com' { include role::web }
node default { include role::baseline }
Defensive patterns

Strategy: try-catch

Try / catch

begin
  compiler.compile
rescue Puppet::ParseError => e
  if e.message.include?('Could not find node statement')
    # classification gap: log node names and fall back to a baseline catalog
  end
  raise
end

Prevention

When it happens

Trigger: site.pp contains node 'web1.example.com' { ... } but the compiling node is web2.example.com and there is no node default block; certname or fqdn changed after certificate regeneration; misspelled node names.

Common situations: Classic classification mistake: adding the first node statement silently removes the implicit 'compile main for everyone' behavior; hostname/certname drift; environment whose site.pp was edited for one node only.

Related errors


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