jordansissel/fpm · error · FPM::InvalidPackageConfiguration
metacpan query failed
Error message
metacpan query failed
What it means
Despite the message saying 'metacpan query failed', this error is raised when downloading the tarball fails: fpm has already obtained download_path from metacpan and then fetches url = <cpan_mirror><download_path> via httpfetch. A Net::HTTPServerException (4xx, typically 404 from the mirror) triggers FPM::InvalidPackageConfiguration with this misleading text.
Source
Thrown at lib/fpm/package/cpan.rb:364
release_metadata = JSON.parse(data)
download_url = release_metadata['hits']['hits'][0]['_source']['download_url']
download_path = URI.parse(download_url).path
tarball = File.basename(download_path)
url_base = "http://www.cpan.org/"
url_base = "#{attributes[:cpan_mirror]}" if !attributes[:cpan_mirror].nil?
url = "#{url_base}#{download_path}"
logger.debug("Fetching perl module", :url => url)
begin
response = httpfetch(url)
rescue Net::HTTPServerException => e
#logger.error("Download failed", :error => response.status_line,
#:url => url)
logger.error("Download failed", :error => e, :url => url)
raise FPM::InvalidPackageConfiguration, "metacpan query failed"
end
File.open(build_path(tarball), "w") do |fd|
#response.read_body { |c| fd.write(c) }
fd.write(response.body)
end
return build_path(tarball)
end # def download
def search_module(module_name, version=nil)
logger.info("Asking metacpan about a module", :module => module_name, :version => version)
metacpan_api_url = "#{attributes[:cpan_metacpan_api_url]}/v1/module/_search"
metacpan_api_query = <<-EOS
{
"query": {
"bool": {
"must": [
{ "term": { "module.name": "#{module_name}" } },View on GitHub (pinned to b6d77ba72a)
Solutions
- Take the logged url value and curl -I it to see the exact status from your mirror
- Switch to a complete mirror: --cpan-mirror http://www.cpan.org/ (default) or another full mirror from http://mirrors.cpan.org/
- Retry later if the release was just uploaded to CPAN (mirror propagation lag)
- Drop the explicit --version so metacpan resolves a release that definitely exists on mirrors
Example fix
# before fpm -s cpan -t deb Foo --cpan-mirror http://minicpan.local # 404 -> 'metacpan query failed' # after fpm -s cpan -t deb Foo --cpan-mirror http://www.cpan.org/
Defensive patterns
Strategy: retry
Validate before calling
require 'net/http'
# HEAD-check the exact tarball URL fpm will fetch from your mirror
url = URI.join(mirror_url, download_path) # e.g. http://www.cpan.org/authors/id/.../Foo-1.00.tar.gz
code = Net::HTTP.start(url.host, url.port) { |http| http.head(url.request_uri).code }
abort "mirror says HTTP #{code} for #{url}" unless code == '200' Try / catch
mirrors = ['http://www.cpan.org/', 'http://cpan.cpantesters.org/']
begin
pkg.input('Foo') # uses attributes[:cpan_mirror]
rescue FPM::InvalidPackageConfiguration => e
raise unless e.message.include?('metacpan query failed') # misleading name: this is the mirror download
raise if mirrors.empty?
pkg.attributes[:cpan_mirror] = mirrors.shift
retry
end Prevention
- Use a full CPAN mirror, not a minicpan, when building with -s cpan
- For freshly released modules, wait for mirror propagation before packaging
- HEAD-check the download URL in a preflight step so failures are attributed to the mirror, not metacpan
When it happens
Trigger: fpm -s cpan fetches e.g. http://www.cpan.org/authors/id/.../Foo-1.00.tar.gz and the mirror returns 404: the mirror is out of sync or incomplete (common with small --cpan-mirror values like a minicpan), the release was just uploaded and has not propagated, or the resolved version does not exist as a file on that mirror.
Common situations: Using --cpan-mirror pointing at a partial/minicpan mirror that lacks authors/ paths; a custom mirror with a different URL layout (missing trailing content); packaging a freshly indexed release before mirrors sync; corporate proxy returning 403 on the CPAN host.
Related errors
- I don't know how to build #{name}. No Makefile.PL nor Build.
- metacpan release query failed
- #{self.class.name} does not yet support reading #{self.type}
- #{self.class.name} does not yet support creating #{self.type
- Parent directory does not exist: #{File.dirname(output_path)
AI-assisted analysis of jordansissel/fpm@b6d77ba72a (2026-08-21).
Data as JSON: /api/errors/6dcb00c4c7f0194c.
Report an issue: GitHub.