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

'%{module_name}' (%{version}) requested; installation confli

Error message

'%{module_name}' (%{version}) requested; installation conflict

What it means

Raised by the Upgrader as Puppet::ModuleTool::Errors::InstallConflictError during the pre-flight over resolved releases: for a release about to be installed, the corresponding directory (by short name, rel.name.split('-').last) is already occupied by an installed module whose forge_name does not match the release — i.e. two different modules claim the same directory name. The error carries :directory and :metadata of the squatter so you can see exactly what occupies the path.

Source

Thrown at lib/puppet/module_tool/applications/upgrader.rb:163

            Puppet.info _("Resolving dependencies ...")
            releases = SemanticPuppet::Dependency.resolve(graph)
          rescue SemanticPuppet::Dependency::UnsatisfiableGraph
            raise NoVersionsSatisfyError, results.merge(:requested_name => name)
          end

          releases.each do |rel|
            mod = installed_modules_source.by_name[rel.name.split('-').last]
            next unless mod
            next if mod.has_metadata? && mod.forge_name.tr('/', '-') == rel.name

            if rel.name != name
              dependency = {
                :name => rel.name,
                :version => rel.version
              }
            end

            raise InstallConflictError,
                  :requested_module => name,
                  :requested_version => options[:version] || 'latest',
                  :dependency => dependency,
                  :directory => mod.path,
                  :metadata => mod.metadata
          end

          child = releases.find { |x| x.name == name }

          unless forced?
            if child.version == results[:installed_version]
              versions = graph.dependencies[name].map(&:version)
              newer_versions = versions.select { |v| v > results[:installed_version] }

              raise VersionAlreadyInstalledError,
                    :module_name => name,
                    :requested_version => results[:requested_version],
                    :installed_version => results[:installed_version],

View on GitHub (pinned to e227c27540)

Solutions

  1. Read the error's :directory field and move or uninstall the occupying module: `puppet module uninstall <old-author-name>` or mv the directory aside
  2. If the occupying content is unmanaged junk, delete the directory and rerun the upgrade
  3. Prefer the Forge namespaced module and delete the third-party duplicate from the modulepath
  4. Re-run `puppet module upgrade <name>` once the conflicting directory no longer holds a mismatched module

Example fix

# before
$ puppet module upgrade puppetlabs-firewall
# Error: 'puppetlabs-firewall' (latest) requested; installation conflict
# ... /etc/puppetlabs/code/environments/production/modules/firewall

# after
$ mv modules/firewall modules/firewall-old-puppet
$ puppet module upgrade puppetlabs-firewall
Defensive patterns

Strategy: try-catch

Validate before calling

# Before upgrading, ensure every directory matching a release's short name is either absent or the same module
short = name.split('-').last
existing = env.modules.find { |m| m.name == short }
if existing && !(existing.has_metadata? && existing.forge_name.tr('/', '-') == name)
  abort "directory '#{short}' is occupied by #{existing.forge_name || 'an unmanaged module'} — move it first"
end

Try / catch

begin
  Puppet::ModuleTool::Applications::Upgrader.new(name, options).run
rescue Puppet::ModuleTool::Errors::InstallConflictError => e
  # e.data[:directory] names the occupied path; quarantine it and retry
  FileUtils.mv(conflicting_dir, "#{conflicting_dir}.conflict")
  retry
end

Prevention

When it happens

Trigger: Upgrading module A pulls in dependency 'puppetlabs-apt', but the environment's 'apt' directory currently holds a differently-authored module (e.g. puppet-apt) or a module without matching metadata, so installing the release would overwrite foreign content.

Common situations: Hand-installed or community modules sharing short names with Forge modules; author renames (puppet-xxx to puppetlabs-xxx) leaving the old copy in place; manually created directories with the same name as a dependency; modules copied in without metadata.json (has_metadata? false).

Related errors


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