puppetlabs/puppet · error · Puppet::Error

Could not list gems: %{detail}

Error message

Could not list gems: %{detail}

What it means

The puppetserver_gem provider executes 'puppetserver gem list --remote' (with any source option) and re-raises as Puppet::Error 'Could not list gems' carrying the underlying execution detail when the command exits non-zero. It means Puppet could not enumerate gems in the Puppet Server JRuby environment - typically the puppetserver CLI is broken or the remote gem source was unreachable.

Source

Thrown at lib/puppet/provider/package/puppetserver_gem.rb:64

      command_options << '--remote'
    end

    if options[:source]
      command_options << '--source' << options[:source]
    end

    if options[:justme]
      gem_regex = '\A' + options[:justme] + '\z'
      command_options << gem_regex
    end

    if options[:local]
      list = execute_rubygems_list_command(command_options)
    else
      begin
        list = puppetservercmd(command_options)
      rescue Puppet::ExecutionFailure => detail
        raise Puppet::Error, _("Could not list gems: %{detail}") % { detail: detail }, detail.backtrace
      end
    end

    # When `/tmp` is mounted `noexec`, `puppetserver gem list` will output:
    # *** LOCAL GEMS ***
    # causing gemsplit to output:
    # Warning: Could not match *** LOCAL GEMS ***
    gem_list = list
               .lines
               .select { |x| x =~ /^(\S+)\s+\((.+)\)/ }
               .map { |set| gemsplit(set) }

    if options[:justme]
      gem_list.shift
    else
      gem_list
    end
  end

View on GitHub (pinned to e227c27540)

Solutions

  1. Read the %{detail} text - it contains the exit status/stderr of the underlying command; run 'puppetserver gem list --remote' manually as root to reproduce
  2. Fix network/proxy egress to the gem source, or point source at an internal mirror (pass '--clear-sources' via install_options if only that mirror should be used)
  3. Verify puppetserver is installed at /opt/puppetlabs/bin/puppetserver and 'puppetserver gem list' succeeds
  4. If this node should not manage server-side gems, remove the puppetserver_gem resources from its role

Example fix

// before
package { 'deep_merge':
  ensure   => '1.2.1',
  provider => puppetserver_gem,
  source   => 'https://rubygems.org',
}
// after - internal mirror reachable from the node
package { 'deep_merge':
  ensure   => '1.2.1',
  provider => puppetserver_gem,
  source   => 'https://gems.internal.example.com',
}
Defensive patterns

Strategy: retry

Validate before calling

# Ruby: verify the gem source is reachable before the run manages puppetserver gems
require 'net/https'
require 'uri'
def gem_source_reachable?(url, timeout = 10)
  uri = URI(url)
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = (uri.scheme == 'https')
  http.open_timeout = timeout
  http.get(uri.request_uri).is_a?(Net::HTTPSuccess)
rescue StandardError
  false
end

Try / catch

retries ||= 0
begin
  gems = Puppet::Type.type(:package).provider(:puppetserver_gem).gemlist(local: false)
rescue Puppet::Error => e
  if (retries += 1) <= 3 && e.message =~ /Could not list gems/
    sleep(2**retries)
    retry
  end
  raise
end

Prevention

When it happens

Trigger: Any package resource with provider => puppetserver_gem (gemlist runs during prefetch/query with local: false) on a host where /opt/puppetlabs/bin/puppetserver fails: no network egress to rubygems.org, proxy misconfiguration, puppetserver not installed, or source => pointing at a dead gem repository.

Common situations: Air-gapped nodes without a gem mirror; typo'd or unavailable source URL; puppetserver package removed but the catalog still manages its gems; slow JVM startup or timeouts on the puppetserver CLI.

Related errors


AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21). Data as JSON: /api/errors/207b03e4fbf6b721. Report an issue: GitHub.