puppetlabs/puppet · error · Puppet::ModuleTool::Errors::NoCandidateReleasesError

Could not %{action} '%{module_name}'; no releases are availa

Error message

Could not %{action} '%{module_name}'; no releases are available from %{source}

What it means

Installer raises Puppet::ModuleTool::NoCandidateReleasesError when the dependency graph built for the target module has no release entries for it — graph.dependencies[name] is empty — meaning the module repository (Forge at module_repository.host) returned nothing installable for that name. The error includes the source host so the user knows where the lookup failed.

Source

Thrown at lib/puppet/module_tool/applications/installer.rb:137

            installed_range = ">=#{version} #{version.major}.x"
            graph.add_constraint('installed', mod, installed_range) do |node|
              Puppet::Module.parse_range(installed_range).include? node.version
            end

            release.mod.dependencies.each do |dep|
              dep_name = dep['name'].tr('/', '-')

              range = dep['version_requirement']
              graph.add_constraint("#{mod} constraint", dep_name, range) do |node|
                Puppet::Module.parse_range(range).include? node.version
              end
            end
          end

          # Ensure that there is at least one candidate release available
          # for the target package.
          if graph.dependencies[name].empty?
            raise NoCandidateReleasesError, results.merge(:module_name => name, :source => module_repository.host, :requested_version => options[:version] || :latest)
          end

          begin
            Puppet.info _("Resolving dependencies ...")
            releases = SemanticPuppet::Dependency.resolve(graph)
          rescue SemanticPuppet::Dependency::UnsatisfiableGraph => e
            unsatisfied = nil

            if e.respond_to?(:unsatisfied) && e.unsatisfied
              constraints = {}
              # If the module we're installing satisfies all its
              # dependencies, but would break an already installed
              # module that depends on it, show what would break.
              if name == e.unsatisfied
                graph.constraints[name].each do |mod, range, _|
                  next unless mod.split.include?('constraint')

                  # If the user requested a specific version or range,

View on GitHub (pinned to e227c27540)

Solutions

  1. Verify the exact slug on the Forge (https://forgeapi.puppet.com/v3/modules?query=<name>) and correct spelling/author.
  2. If using a private Forge, confirm module_repository / --module_repository points at the host that actually hosts the module.
  3. Check network reachability of the Forge API host from this node (curl the forge URL).
  4. If releases were yanked, pin to an available version or vendor the tarball and install from the local file.

Example fix

# before
puppet module install puppetlabs-stblib

# after
puppet module install puppetlabs-stdlib
Defensive patterns

Strategy: validation

Validate before calling

require 'net/http'

uri = URI("#{Puppet.settings[:module_repository]}/api/v1/releases?module=#{slug}")
abort 'module not found on forge' unless Net::HTTP.get_response(uri).code == '200'

Try / catch

begin
  installer.run
rescue Puppet::ModuleTool::NoCandidateReleasesError => e
  abort "check slug spelling and forge connectivity: #{e.message}"
end

Prevention

When it happens

Trigger: `puppet module install <author>-<name>` where the slug is misspelled, the module does not exist on the configured Forge, all releases were deleted/deprecated, or a proxy/firewall made the Forge API return an empty result set that was swallowed into an empty graph.

Common situations: Typos in module names in a Puppetfile or CLI; modules removed from the Forge or renamed; pointing module_repository at a private Forge that lacks the module; air-gapped environments where the forge host is unreachable but errors surface as empty results; forgetting the author- prefix on a private forge that requires it.

Related errors


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