puppetlabs/puppet · error · Puppet::Error

Failed to update to version %{should}, got version %{version

Error message

Failed to update to version %{should}, got version %{version} instead

What it means

apt.rb:182: after installing from an explicit source file with a versioned ensure, the provider reads the installed version via query and calls insync?; if dpkg reports a version different from the requested one, it raises 'Failed to update to version %{should}, got version %{version} instead'. It is a post-install verification failure: apt-get ran, but the resulting package version does not satisfy ensure.

Source

Thrown at lib/puppet/provider/package/apt.rb:182

      cmd << str
    end
    # rubocop:enable Style/RedundantCondition

    unhold if properties[:mark] == :hold
    begin
      aptget(*cmd)
    ensure
      hold if @resource[:mark] == :hold
    end

    # If a source file was specified, we must make sure the expected version was installed from specified file
    if source && !%i[present installed].include?(should)
      is = query
      raise Puppet::Error, _("Could not find package %{name}") % { name: name } unless is

      version = is[:ensure]

      raise Puppet::Error, _("Failed to update to version %{should}, got version %{version} instead") % { should: should, version: version } unless
        insync?(version)
    end
  end

  # What's the latest package version available?
  def latest
    output = aptcache :policy, @resource[:name]

    if output =~ /Candidate:\s+(\S+)\s/
      Regexp.last_match(1)
    else
      err _("Could not find latest version")
      nil
    end
  end

  #
  # preseeds answers to dpkg-set-selection from the "responsefile"

View on GitHub (pinned to e227c27540)

Solutions

  1. Read the exact installed version from the message, then `dpkg-deb -f <source.deb> Version` and copy that string verbatim into ensure.
  2. Account for Debian epochs and revisions in ensure (e.g. '1:2.0.1-1~bpo9+1' must match character-for-character what dpkg reports).
  3. Ensure the source file really is the one being installed — if a repo version wins, remove the conflicting repo entry or pin the package.

Example fix

# before
package { 'nginx': ensure => '1.18.0', source => '/tmp/nginx.deb' } # deb Version is 1.18.0-2

# after
package { 'nginx': ensure => '1.18.0-2', source => '/tmp/nginx.deb' }
Defensive patterns

Strategy: validation

Validate before calling

# ensure must equal dpkg-deb's Version exactly
want = '1.18.0'
have = `dpkg-deb -f /tmp/nginx.deb Version`.strip
fail "ensure version mismatch: wanted #{want}, deb has #{have}" unless want == have

Try / catch

begin
  provider.install
rescue Puppet::Error => e
  raise unless e.message =~ /Failed to update to version/
  installed = e.message[/got version (\S+)/, 1]
  resource[:ensure] = installed # adopt reality or fix the artifact; then re-run
end

Prevention

When it happens

Trigger: package { X: ensure => '1.2.3', source => '...deb' } where the staged deb's Version: field is not 1.2.3 (e.g. Debian revision differences like 1.2.3-1 vs 1.2.3, or an epoch like 2:1.2.3), or apt resolved a different version from the repos because the source install was overridden.

Common situations: Setting ensure to the upstream tarball version while the deb carries a distro revision; epochs (1:...) omitted from ensure; the same package name available in a configured repo at another version and installed instead of the staged file; typo in the version string.

Related errors


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