puppetlabs/puppet · error · Puppet::Error
cannot lookup multiple files
Error message
cannot lookup multiple files
What it means
The http file_metadata terminus serves metadata for a single HTTP(S) URL via HEAD, falling back to a one-byte Range GET when the server answers 403/405 (e.g. S3 presigned URLs). Puppet's search action means metadata for many files / recursive traversal, which plain web servers cannot express, so search unconditionally raises Puppet::Error 'cannot lookup multiple files'.
Source
Thrown at lib/puppet/indirector/file_metadata/http.rb:34
uri = URI(request.uri)
client = Puppet.runtime[:http]
head = client.head(uri, options: { include_system_store: true })
return create_httpmetadata(head, checksum_type) if head.success?
case head.code
when 403, 405
# AMZ presigned URL and puppetserver may return 403
# instead of 405. Fallback to partial get
get = partial_get(client, uri)
return create_httpmetadata(get, checksum_type) if get.success?
end
nil
end
def search(request)
raise Puppet::Error, _("cannot lookup multiple files")
end
private
def partial_get(client, uri)
client.get(uri, headers: { 'Range' => 'bytes=0-0' }, options: { include_system_store: true })
end
def create_httpmetadata(http_request, checksum_type)
metadata = Puppet::FileServing::HttpMetadata.new(http_request)
metadata.checksum_type = checksum_type if checksum_type
metadata.collect
metadata
end
end
View on GitHub (pinned to e227c27540)
Solutions
- Point each resource at a single file URL and generate one resource per file (e.g. from a manifest loop or a generated list).
- Remove recurse / recurse_remote from resources whose source scheme is http or https.
- If recursion is required, sync the remote tree into a module or another puppet-served location and use a puppet:/// source.
Example fix
# before
file { '/opt/app':
ensure => directory,
recurse => true,
source => 'https://repo.example.com/app/1.2.3/',
}
# Error: cannot lookup multiple files
# after: stage the tree in a module, recurse over puppet://
file { '/opt/app':
ensure => directory,
recurse => true,
source => 'puppet:///modules/app_files/1.2.3',
} Defensive patterns
Strategy: validation
Validate before calling
def http_source?(uri) %w[http https].include?(URI.parse(uri).scheme.to_s) end raise ArgumentError, 'http(s) sources cannot be recursive' if http_source?(source) && opts[:recurse]
Type guard
def single_http_file?(uri)
u = URI.parse(uri.to_s)
%w[http https].include?(u.scheme.to_s) && !u.path.to_s.end_with?('/')
end Prevention
- Treat http(s) file sources as single-file only by design.
- Review any resource mixing recurse with a non-puppet scheme.
- Serve trees from modules or fileserver mounts when recursion is needed.
When it happens
Trigger: A file (or similar) resource whose source is 'http://' or 'https://' combined with recurse => true or sources => containing multiple http URLs; a Ruby call to Puppet::FileServing::Metadata.indirection.search with an http(s) URI.
Common situations: Porting a recursive copy from puppet:// to a web server or object store; pointing file resources at artifact directories served by nginx/S3; expecting directory listing semantics from presigned URLs.
Related errors
- Listing remote file buckets is not allowed
- Relative paths must not be fully qualified
- Fileset recurse parameter must not be a number anymore, plea
- The directory '%{path}' contains %{entries} entries, which e
- Find %{uri} resulted in 404 with the message: %{body}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/02fa5514b0121bc2.
Report an issue: GitHub.