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

  1. Take the logged url value and curl -I it to see the exact status from your mirror
  2. Switch to a complete mirror: --cpan-mirror http://www.cpan.org/ (default) or another full mirror from http://mirrors.cpan.org/
  3. Retry later if the release was just uploaded to CPAN (mirror propagation lag)
  4. 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

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


AI-assisted analysis of jordansissel/fpm@b6d77ba72a (2026-08-21). Data as JSON: /api/errors/6dcb00c4c7f0194c. Report an issue: GitHub.