puppetlabs/puppet · error · Puppet::Error
Find %{uri} resulted in 404 with the message: %{body}
Error message
Find %{uri} resulted in 404 with the message: %{body} What it means
The catalog REST terminus turns a server 404 into a Puppet::Error whose message embeds the request path and the server's response body — but only when the request carried options[:fail_on_404] truthy; otherwise a 404 maps to nil (catalog not found). This preserves the indirector convention that find returns nil for missing resources while letting agent runs fail loudly on a missing catalog.
Source
Thrown at lib/puppet/indirector/catalog/rest.rb:46
_, catalog = api.post_catalog(
request.key,
facts: request.options[:facts_for_catalog],
environment: request.environment.to_s,
configured_environment: request.options[:configured_environment],
check_environment: request.options[:check_environment],
transaction_uuid: request.options[:transaction_uuid],
job_uuid: request.options[:job_id],
static_catalog: request.options[:static_catalog],
checksum_type: checksum_type
)
catalog
rescue Puppet::HTTP::ResponseError => e
if e.response.code == 404
return nil unless request.options[:fail_on_404]
_, body = parse_response(e.response)
msg = _("Find %{uri} resulted in 404 with the message: %{body}") % { uri: elide(e.response.url.path, 100), body: body }
raise Puppet::Error, msg
else
raise convert_to_http_error(e.response)
end
end
end
View on GitHub (pinned to e227c27540)
Solutions
- Read the body in the message — puppetserver's 404 body states what was not found (node vs environment); fix that on the server side
- Verify the agent's environment setting and that the environment exists on the master before failing hard
- If nil-not-found semantics are wanted (tooling), call find without fail_on_404
Example fix
# before (ruby) catalog = Puppet::Resource::Catalog.indirection.find(name, fail_on_404: true) # 404 => Puppet::Error # after: tolerate missing catalogs catalog = Puppet::Resource::Catalog.indirection.find(name) # 404 => nil
Defensive patterns
Strategy: try-catch
Validate before calling
# ruby # choose semantics before the call; only pass fail_on_404 when missing is fatal catalog = Puppet::Resource::Catalog.indirection.find(name) raise 'catalog missing' if catalog.nil? && strict
Type guard
def catalog_present?(name) !Puppet::Resource::Catalog.indirection.find(name).nil? end
Try / catch
begin
Puppet::Resource::Catalog.indirection.find(name, fail_on_404: true)
rescue Puppet::Error => e
raise unless e.message.include?('404')
nil # or retry against the primary master if routed to a compile server
end Prevention
- Reserve fail_on_404 for agent-run paths where nil would hide broken compilation
- Read the 404 body before assuming network trouble — it names the missing node or environment
- In inventory scripts, prefer default nil-semantics find and handle nil explicitly
When it happens
Trigger: Puppet::Resource::Catalog.indirection.find(name, fail_on_404: true) against a server that answers 404 (unknown node, unknown environment, or a request routed to a server without the node's data); agent runs, which set fail_on_404 so a missing catalog aborts instead of silently returning nil.
Common situations: The requested environment does not exist on the master (common after environment renames); a load balancer or SRV routing sending the catalog GET to a compile server that does not know the node; agents pointing at a compile-masters tier during migration.
Related errors
- Find %{uri} resulted in 404 with the message: %{body}
- PUT does not accept options
- Unable to verify the SSL certificate at %{uri}
- No title provided and %{type} is not a valid resource refere
- Could not find resource '%{res}' in parameter '%{param}'
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/60016e0e173a9ef2.
Report an issue: GitHub.