{"record":{"id":"b81594a7cd817826","repo":"puppetlabs/puppet","slug":"find-uri-resulted-in-404-with-the-message-bo-b81594","errorCode":null,"errorMessage":"Find %{uri} resulted in 404 with the message: %{body}","messagePattern":"Find %(.+?) resulted in 404 with the message: %(.+?)","errorType":"http","errorClass":"Puppet::Error","httpStatus":404,"severity":"error","filePath":"lib/puppet/indirector/file_metadata/rest.rb","lineNumber":29,"sourceCode":"    url = URI.parse(Puppet::Util.uri_encode(request.uri))\n    session = Puppet.lookup(:http_session)\n    api = session.route_to(:fileserver, url: url)\n\n    _, file_metadata = api.get_file_metadata(\n      path: Puppet::Util.uri_unescape(url.path),\n      environment: request.environment.to_s,\n      links: request.options[:links],\n      checksum_type: request.options[:checksum_type],\n      source_permissions: request.options[:source_permissions]\n    )\n    file_metadata\n  rescue Puppet::HTTP::ResponseError => e\n    if e.response.code == 404\n      return nil unless request.options[:fail_on_404]\n\n      _, body = parse_response(e.response)\n      msg = _(\"Find %{uri} resulted in 404 with the message: %{body}\") % { uri: elide(e.response.url.path, 100), body: body }\n      raise Puppet::Error, msg\n    else\n      raise convert_to_http_error(e.response)\n    end\n  end\n\n  def search(request)\n    url = URI.parse(Puppet::Util.uri_encode(request.uri))\n    session = Puppet.lookup(:http_session)\n    api = session.route_to(:fileserver, url: url)\n\n    _, file_metadatas = api.get_file_metadatas(\n      path: Puppet::Util.uri_unescape(url.path),\n      environment: request.environment.to_s,\n      recurse: request.options[:recurse],\n      recurselimit: request.options[:recurselimit],\n      max_files: request.options[:max_files],\n      ignore: request.options[:ignore],\n      links: request.options[:links],","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/indirector/file_metadata/rest.rb#L11-L47","documentation":"The REST terminus for the file_metadata indirection performs the metadata lookup (HEAD/GET) for a file source against the fileserver API. A 404 normally yields nil, but with options[:fail_on_404] - which Puppet's compiler sets when resolving file resource sources - it raises Puppet::Error with the elided URI and the server's message, e.g. 'Find /puppet/v3/file_metadata/... resulted in 404 with the message: Not Found: ...'. This is the classic error behind 'Error: Could not retrieve file metadata' during agent runs.","triggerScenarios":"Compiling/applying a catalog with source 'puppet:///modules/mod/missing' while fail_on_404 is set; requesting metadata for a file that exists in a different environment; Ruby calls to Puppet::FileServing::Metadata.indirection.find(..., fail_on_404: true).","commonSituations":"Deleted or renamed module files still referenced by manifests; branch-only files not merged to the node's environment; new nodes pinned to an environment lacking the module; fileserver mount path changes after server upgrades.","solutions":["Verify the file exists in the node's environment: environments/<env>/modules/<mod>/files/<path> on the server.","Check the node's environment (puppet config print environment) and the module's presence in that environment.","Fix spelling, case, and the puppet:///modules/<mod>/ prefix mapping (it addresses the module's files/ directory).","In direct API use, omit fail_on_404 and handle a nil result yourself when absence is expected."],"exampleFix":"# before\nmeta = Puppet::FileServing::Metadata.indirection.find(\n  'puppet:///modules/app/etc/app.conf', fail_on_404: true)\n# raises for a missing file\n\n# after: treat absence explicitly\nmeta = Puppet::FileServing::Metadata.indirection.find(\n  'puppet:///modules/app/etc/app.conf')\nreturn if meta.nil?","handlingStrategy":"try-catch","validationCode":"meta = Puppet::FileServing::Metadata.indirection.find(uri)\nreturn if meta.nil? # 404 surfaces as nil when fail_on_404 is unset\nfail 'source missing: ' + uri if ENV['STRICT_SOURCES']","typeGuard":null,"tryCatchPattern":"begin\n  meta = Puppet::FileServing::Metadata.indirection.find(uri, fail_on_404: true)\nrescue Puppet::Error => e\n  raise unless e.message.include?('404')\n  fail 'file source missing: ' + uri.to_s\nend","preventionTips":["Resolve every file source during CI catalog compilation.","Keep module files and manifests in the same change/PR.","Omit fail_on_404 and handle nil when absence is a normal state."],"tags":["puppet","file-metadata","fileserver","http-404","catalog-compilation"],"backgroundTag":"http-404-not-found","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}