puppetlabs/puppet · error · Puppet::ModuleTool::Errors::NoVersionsSatisfyError
Could not %{action} '%{module_name}' (%{version}); no versio
Error message
Could not %{action} '%{module_name}' (%{version}); no version satisfies all dependencies What it means
After the resolver intersects every version range imposed on a dependency and selects candidate releases from the Forge, it prefers final releases over prereleases (semver.special == '') and falls back to prereleases only when no final release matches. If the filtering still yields zero releases (valid_versions.last is nil), NoVersionsSatisfyError aborts the operation: no published release of that dependency satisfies the combined constraints.
Source
Thrown at lib/puppet/module_tool/shared_behaviors.rb:132
action = :upgrade
elsif @installed[mod].empty?
action = :install
end
if action == :upgrade
@conditions.each { |_, conds| conds.delete_if { |c| c[:module] == mod } }
end
versions = @versions[mod.to_s].select { |h| range === h[:semver] }
valid_versions = versions.select { |x| x[:semver].special == '' }
valid_versions = versions if valid_versions.empty?
version = valid_versions.last
unless version
req_module = @module_name
req_versions = @versions[@module_name.to_s].map { |v| v[:semver] }
raise NoVersionsSatisfyError,
:requested_name => req_module,
:requested_version => @version || annotated_version(req_module, req_versions),
:installed_version => @installed[@module_name].empty? ? nil : @installed[@module_name].first.version,
:dependency_name => mod,
:conditions => @conditions[mod],
:action => @action
end
seen[mod] = version
{
:module => mod,
:version => version,
:action => action,
:previous_version => @installed[mod].empty? ? nil : @installed[mod].first.version,
:file => @urls["#{mod}@#{version[:vstring]}"],
:path => if action == :install
@options[:target_dir]View on GitHub (pinned to e227c27540)
Solutions
- Read dependency_name and the conditions in the error message, then widen that version_requirement in your metadata.json to include at least one published release.
- Install another release of the module you are requesting whose dependency set matches reality: puppet module install author/mod --version X.Y.Z.
- Upgrade or remove the other module imposing the conflicting half of the range (it shows up in the conditions list).
- Confirm on the Forge (forge.puppet.com / forgeapi.puppet.com) which releases of the dependency actually exist before tightening any range.
Example fix
# before (metadata.json) — intersection with the other dependent's 'stdlib < 9.0.0' is empty
{"dependencies": [{"name": "puppetlabs/stdlib", "version_requirement": ">= 9.5.0"}]}
# after — a range both dependents accept
{"dependencies": [{"name": "puppetlabs/stdlib", "version_requirement": ">= 8.0.0 < 10.0.0"}]} Defensive patterns
Strategy: try-catch
Validate before calling
require 'semantic_puppet'
releases = forge_releases_for(dep_name) # e.g. ['1.0.0', '8.6.0', '9.4.0']
ranges = constraints_on(dep_name).map { |r| SemanticPuppet::VersionRange.parse(r) }
shared = ranges.inject(&:&)
ok = shared && releases.any? { |v| shared === SemanticPuppet::Version.parse(v) }
abort "no release of #{dep_name} satisfies #{ranges.map(&:to_s).join(' & ')}" unless ok Try / catch
begin # puppet module install author/mod rescue Puppet::ModuleTool::Errors::NoVersionsSatisfyError => e # e.message names the dependency and the unsatisfiable conditions warn e.message exit 1 end
Prevention
- Write ranges as intervals ('>= x.y.z < X.0.0') that include real published releases.
- Check the Forge release list before adding or tightening a dependency pin.
- Resolve dependencies in CI (r10k puppetfile install or a module install dry-run) before merging.
- Avoid depending on prereleases unless the range explicitly allows them.
When it happens
Trigger: 'puppet module install' or 'puppet module upgrade' where @versions[mod].select { |h| range === h[:semver] } is empty: constraints intersect to something like '>= 3.2.0 < 3.2.0', or the only needed release was never published or was deleted from the Forge.
Common situations: Over-tight metadata.json ranges (typos like '>= 1.2.3 < 1.2.3'); two modules pinning disjoint ranges of a shared dependency (stdlib >= 9 vs < 9); depending on a yanked release; dependency renamed so its old name has no matching releases.
Related errors
- '%{module_name}' (%{version}) requested; Invalid dependency
- Could not find a valid module at %{path}
- Dependency conflict for %{module_name}: Dependency %{name} w
- Invalid 'name' field in metadata.json: %{err}
- Invalid 'version' field in metadata.json: %{err}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/89725e20d564acb3.
Report an issue: GitHub.