puppetlabs/puppet · error · ArgumentError
Could not find terminus %{terminus_class} for indirection %{
Error message
Could not find terminus %{terminus_class} for indirection %{name} What it means
After the blank check, validate_terminus_class resolves the terminus class via Puppet::Indirector::Terminus.terminus_class(name, terminus_class), which requires 'puppet/indirector/<indirection>/<terminus>'. If no such class exists, ArgumentError 'Could not find terminus X for indirection Y' is raised at assignment time, before any request is made.
Source
Thrown at lib/puppet/indirector/indirection.rb:188
def reset_terminus_class
@terminus_class.value = nil
end
# Specify the terminus class to use.
def terminus_class=(klass)
validate_terminus_class(klass)
@terminus_class.value = klass
end
# This is used by terminus_class= and cache=.
def validate_terminus_class(terminus_class)
unless terminus_class and terminus_class.to_s != ""
raise ArgumentError, _("Invalid terminus name %{terminus_class}") % { terminus_class: terminus_class.inspect }
end
unless Puppet::Indirector::Terminus.terminus_class(name, terminus_class)
raise ArgumentError, _("Could not find terminus %{terminus_class} for indirection %{name}") %
{ terminus_class: terminus_class, name: name }
end
end
# Expire a cached object, if one is cached. Note that we don't actually
# remove it, we expire it and write it back out to disk. This way people
# can still use the expired object if they want.
def expire(key, options = {})
request = request(:expire, key, nil, options)
return nil unless cache? && !request.ignore_cache_save?
instance = cache.find(request(:find, key, nil, options))
return nil unless instance
Puppet.info _("Expiring the %{cache} cache of %{instance}") % { cache: name, instance: instance.name }
# Set an expiration date in the pastView on GitHub (pinned to e227c27540)
Solutions
- List valid names for the indirection: Puppet::Indirector::Terminus.terminus_classes(:catalog), or inspect lib/puppet/indirector/<indirection>/ on the installed gem.
- Install or require the gem/module that provides the custom terminus on the failing host.
- Fix spelling and confirm the name matches the indirection (e.g. compiler for catalog on a server).
- Confirm the setting sits in the right run-mode section ([agent] vs [server]/[master]).
Example fix
# before [main] catalog_terminus = catelog # typo # after [main] catalog_terminus = compiler
Defensive patterns
Strategy: validation
Validate before calling
desired = 'compiler' unless Puppet::Indirector::Terminus.terminus_class(:catalog, desired) raise ArgumentError, 'terminus not installed: ' + desired end Puppet::Resource::Catalog.indirection.terminus_class = desired
Prevention
- Smoke-test custom termini by requiring them before switching settings.
- Pin gem versions that provide termini alongside the puppet version.
- Automate config validation with puppet config print in CI.
When it happens
Trigger: A misspelled terminus in puppet.conf (node_terminus = exec-like typos, catalog_terminus = catelog); a custom terminus whose gem or module is not installed on this node; a terminus name that exists only for a different indirection or puppet version.
Common situations: Custom termini shipped as gems present on compile servers but missing on agents (or vice versa); documentation copy-paste across puppet versions where names changed; PE/open-source version drift.
Related errors
- Invalid terminus name %{terminus_class}
- Could not find terminus %{terminus_class} for indirection %{
- Listing remote file buckets is not allowed
- Could not find %{request} to destroy
- Could not read MessagePack data for %{indirection} %{key}: %
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/98cbecd7f9c11756.
Report an issue: GitHub.