jordansissel/fpm · error · FPM::InvalidPackageConfiguration
metacpan release query failed
Error message
metacpan release query failed
What it means
While resolving a Perl module to a downloadable tarball, fpm POSTs an Elasticsearch-style query to the metacpan API at /v1/release/_search to get the download_url for Distribution-VERSION. If the HTTP layer raises Net::HTTPServerException (any 4xx response), fpm logs the underlying error and re-raises FPM::InvalidPackageConfiguration with this message.
Source
Thrown at lib/fpm/package/cpan.rb:342
:distribution => distribution,
:version => cpan_version)
# default to latest version unless we specify one
if cpan_version.nil?
self.version = "#{metadata["version"]}"
else
self.version = "#{cpan_version}"
end
# Search metacpan to get download URL for this version of the module
metacpan_search_url = "#{attributes[:cpan_metacpan_api_url]}/v1/release/_search?_source=download_url"
metacpan_search_query = {"query":{"term":{"name": "#{distribution}-#{self.version}" } } }.to_json
begin
search_response = httppost(metacpan_search_url,metacpan_search_query)
rescue Net::HTTPServerException => e
logger.error("metacpan release query failed.", :error => e.message,
:url => metacpan_search_url)
raise FPM::InvalidPackageConfiguration, "metacpan release query failed"
end
data = search_response.body
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 => eView on GitHub (pinned to b6d77ba72a)
Solutions
- Reproduce the failing request outside fpm: curl -s -X POST 'https://fastapi.metacpan.org/v1/release/_search?_source=download_url' -H 'Content-Type: application/json' -d '{"query":{"term":{"name":"Foo-1.00"}}}' and inspect the status code
- Check that Distribution-VERSION actually exists on metacpan (search the module on metacpan.org); a wrong --version produces a name term with no release
- Verify --cpan-metacpan-api-url; unset it or set it to https://fastapi.metacpan.org
- If a proxy is involved, configure correct proxy env vars (http_proxy/https_proxy) so the POST is not rejected with 4xx
- Update fpm if you run an old release that uses a retired metacpan endpoint
Example fix
# before fpm -s cpan -t deb Foo --cpan-metacpan-api-url https://metacpan.local # 404 -> metacpan release query failed # after fpm -s cpan -t deb Foo # default URL fpm -s cpan -t deb Foo --cpan-metacpan-api-url https://fastapi.metacpan.org
Defensive patterns
Strategy: retry
Validate before calling
require 'net/http'
uri = URI('https://fastapi.metacpan.org/v1/release/_search?_source=download_url')
begin
resp = Net::HTTP.post(uri, { query: { term: { name: 'Foo-1.00' } } }.to_json,
'Content-Type' => 'application/json')
abort "metacpan returned HTTP #{resp.code}" unless resp.code == '200'
rescue SocketError => e
abort "cannot resolve metacpan: #{e.message}"
end Try / catch
require 'net/http'
3.times do |attempt|
begin
pkg = FPM::Package::CPAN.new
pkg.input('Foo')
break
rescue FPM::InvalidPackageConfiguration => e
raise if attempt == 2 || !e.message.include?('metacpan release query failed')
sleep(2**attempt) # metacpan 4xx: back off for 429, recheck URL for 4xx
warn "retry #{attempt + 1}/3 after metacpan error"
end
end Prevention
- Pin CI jobs to the default --cpan-metacpan-api-url unless a self-hosted metacpan is verified healthy
- Add a preflight curl/Net::HTTP check on the metacpan endpoint before starting the fpm build
- Keep fpm updated so its metacpan query shape tracks the live API
When it happens
Trigger: Calling fpm -s cpan (input/download path) when metacpan answers 4xx to the release _search POST: 404 from an outdated/changed API base URL (--cpan-metacpan-api-url pointing at a wrong or proxied host), 400 for a malformed query, or a corporate proxy returning 403/407. Only HTTP 4xx raises here; DNS failures and connection refused raise different errors.
Common situations: Custom --cpan-metacpan-api-url typo or stale self-hosted metacpan instance; metacpan API schema/endpoint changes after an upgrade; proxy or captive-portal interception of api.metacpan.org; requests behind flaky networks returning 429.
Related errors
- Could not find package metadata. Checked for META.json, META
- I don't know how to build #{name}. No Makefile.PL nor Build.
- metacpan query failed
- #{self.class.name} does not yet support reading #{self.type}
- #{self.class.name} does not yet support creating #{self.type
AI-assisted analysis of jordansissel/fpm@b6d77ba72a (2026-08-21).
Data as JSON: /api/errors/c889c103d690e5a6.
Report an issue: GitHub.