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 REST terminus for the file_content indirection wraps HTTP 404 from the Puppet fileserver API. By default 404 returns nil (treated as file absent); when the request carries options[:fail_on_404], which Puppet sets when resolving file sources during catalog application, it raises Puppet::Error embedding the elided URI path and the server's parsed message body so the missing source is reported loudly instead of silently yielding nil.
Source
Thrown at lib/puppet/indirector/file_content/rest.rb:32
url = URI.parse(Puppet::Util.uri_encode(request.uri))
session = Puppet.lookup(:http_session)
api = session.route_to(:fileserver, url: url)
api.get_file_content(
path: Puppet::Util.uri_unescape(url.path),
environment: request.environment.to_s
) do |data|
content << data
end
Puppet::FileServing::Content.from_binary(content.string)
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
- Verify the file exists server-side: puppet:///modules/mod/path maps to environments/<env>/modules/mod/files/path on the Puppet server.
- Confirm the node's environment matches the environment that contains the file.
- Re-check spelling and case of the source URI and module name.
- If absence is legitimate and you call the API directly, omit fail_on_404 so the lookup returns nil instead of raising.
Example fix
# manifest - before
file { '/etc/app/app.conf':
source => 'puppet:///modules/app/etc/app.con', # typo
}
# after
file { '/etc/app/app.conf':
source => 'puppet:///modules/app/etc/app.conf',
} Defensive patterns
Strategy: fallback
Validate before calling
# do not opt into failing on absence unless absence is fatal
content = Puppet::FileServing::Content.indirection.find(uri) # returns nil on 404
if content.nil?
content = Puppet::FileServing::Content.from_binary(File.binread('/etc/app.conf.default'))
end Try / catch
begin content = Puppet::FileServing::Content.indirection.find(uri, fail_on_404: true) rescue Puppet::Error => e Puppet.warning(uri + ' unavailable, using default') content = Puppet::FileServing::Content.from_binary(DEFAULT) end
Prevention
- Run catalog tests that resolve every file source in CI before deploy.
- Keep environments in sync so sources exist where agents run.
- Audit puppet:/// URIs for typos and case mismatches with lint checks.
When it happens
Trigger: A file resource with source 'puppet:///modules/<mod>/<path>' where the file does not exist on the server in the node's environment; wrong module name or mount; Ruby calls to Puppet::FileServing::Content.indirection.find(uri, fail_on_404: true) for a missing file.
Common situations: Files deleted from a module but still referenced by manifests; environments out of sync (file merged to production while the agent runs a feature branch); case mismatches in paths on case-sensitive servers; fileserver mount renamed.
Related errors
- Find %{uri} resulted in 404 with the message: %{body}
- Invalid entry at %{error_location}: '%{file_text}'
- %{mount} is already mounted at %{name} at %{error_location}
- Invalid mount name format '%{name}'
- Mounts without paths are not usable
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/c31db62d08b29bd4.
Report an issue: GitHub.