puppetlabs/puppet · error · Puppet::ParseError

Could not find template '%{filename}'

Error message

Could not find template '%{filename}'

What it means

Raised by TemplateWrapper#file= when Puppet::Parser::Files.find_template(filename, environment) returns nil for the requested template path. Template lookup resolves '<module>/<path>.erb' against the modules and templatedirs of the COMPILING environment; failure means no such file is visible to that environment. It is a Puppet::ParseError, so it aborts compilation with the exact requested filename in the message.

Source

Thrown at lib/puppet/parser/templatewrapper.rb:68

  end

  # @return [Array<String>] The tags defined in the current scope
  # @api public
  def tags
    raise NotImplementedError, "Call 'all_tags' instead."
  end

  # @return [Array<String>] All the defined tags
  # @api public
  def all_tags
    scope.catalog.tags
  end

  # @api private
  def file=(filename)
    @__file__ = Puppet::Parser::Files.find_template(filename, scope.compiler.environment)
    unless @__file__
      raise Puppet::ParseError, _("Could not find template '%{filename}'") % { filename: filename }
    end
  end

  # @api private
  def result(string = nil)
    if string
      template_source = "inline template"
    else
      string = Puppet::FileSystem.read_preserve_line_endings(@__file__)
      template_source = @__file__
    end

    # Expose all the variables in our scope as instance variables of the
    # current object, making it possible to access them without conflict
    # to the regular methods.
    escaped_template_source = template_source.gsub(/%/, '%%')
    benchmark(:debug, _("Bound template variables for %{template_source} in %%{seconds} seconds") % { template_source: escaped_template_source }) do
      scope.to_hash.each do |name, value|

View on GitHub (pinned to e227c27540)

Solutions

  1. Verify the path maps to a real file: modules/<module>/templates/<path>.erb in the environment that compiles the node.
  2. Check the module is installed in that environment (`puppet module list` / r10k checkout of the branch) and re-sync environments on all compile masters.
  3. Fix casing/typos — template paths are case-sensitive on Linux masters.
  4. For Puppet <4 layout issues, move templates under the module or use epp with the module loader; use inline_template('...') only for tiny strings, not to dodge missing files.

Example fix

# before
file { '/etc/app.conf':
  content => template('app/config.erb'),   # file actually at templates/app/conf.erb
}

# after
file { '/etc/app.conf':
  content => template('app/conf.erb'),
}
Defensive patterns

Strategy: validation

Validate before calling

# Ruby API — probe before rendering:
path = Puppet::Parser::Files.find_template('app/config.erb', env)
render(path) unless path.nil?
# Shell — verify on the compiling master:
#   ls /etc/puppetlabs/code/environments/<env>/modules/app/templates/config.erb

Try / catch

begin
  wrapper.file = 'app/config.erb'
rescue Puppet::ParseError => e
  # template missing in this environment — fall back to a packaged default
  wrapper.result(default_template_string)
end

Prevention

When it happens

Trigger: `template('apache/vhost.erb')` or `file { ...: content => template('app/config.erb') }` where the module lacks templates/config.erb; wrong path casing; template in a module not installed in the compiling environment; `template('custom.erb')` relying on old templatedir behavior that no longer resolves.

Common situations: Compiling master missing a module present on the agent (environment drift between git branches); typos or renamed template files; modules vendored with different case on case-sensitive filesystems; migrating from Puppet 2/3 templatedir usage to module-based template paths.

Related errors


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