puppetlabs/puppet · error · Puppet::ExecutionFailure

Unexpected output from portversion: %{output}

Error message

Unexpected output from portversion: %{output}

What it means

The portupgrade provider's latest could not match portversion output against either the version-status regex or the '** No matching package' marker, so it refuses to guess and raises Puppet::ExecutionFailure including the full raw output. This is a defensive parse failure: the portversion output format is not what the provider understands.

Source

Thrown at lib/puppet/provider/package/portupgrade.rb:156

          Puppet.debug "portupgrade.latest() - Unable to determine new version from (#{otherdata})"
          installedversion
        end
      when "?", "!", "#"
        Puppet.debug "portupgrade.latest() - Comparison Error reported from portversion (#{output})"
        installedversion
      else
        Puppet.debug "portupgrade.latest() - Unknown code from portversion output (#{output})"
        installedversion
      end

    elsif output =~ /^\*\* No matching package /
      # error: output not parsed correctly, error out with nil.
      # Seriously - this section should never be called in a perfect world.
      # as verification that the port is installed has already happened in query.
      raise Puppet::ExecutionFailure, _("Could not find package %{name}") % { name: @resource[:name] }
    else
      # Any other error (dump output to log)
      raise Puppet::ExecutionFailure, _("Unexpected output from portversion: %{output}") % { output: output }
    end
  end

  ###### Query subcommand - return a hash of details if exists, or nil if it doesn't.
  # Used to make sure the package is installed

  def query
    Puppet.debug "portupgrade.query() - Called on #{@resource[:name]}"

    cmdline = ["-qO", @resource[:name]]
    begin
      output = portinfo(*cmdline)
    rescue Puppet::ExecutionFailure => e
      raise Puppet::Error.new(output, e)
    end

    # Check: if output isn't in the right format, return nil
    if output =~ /^(\S+)-([^-\s]+)/

View on GitHub (pinned to e227c27540)

Solutions

  1. Reproduce manually: 'portversion -v <origin>' and inspect the exact line the provider failed on
  2. Force a stable locale for the run (LANG=C LC_ALL=C in the agent environment) since message formats drift under localization
  3. Update the regexes at lib/puppet/provider/package/portupgrade.rb:119/:149 to match your portversion output and upstream the patch
  4. Migrate to the pkgng provider, which parses 'pkg' output instead
Defensive patterns

Strategy: try-catch

Validate before calling

# Ruby: confirm portversion output matches the shapes the provider parses
PORTVERSION_LINE = /\A\S+-[^-\s]+\s+\S\s+.*\z/
def portversion_output_parseable?(origin)
  out = Puppet::Util::Execution.execute(['/usr/local/sbin/portversion', '-v', origin], failonfail: false).to_s
  out.lines.any? { |l| PORTVERSION_LINE.match?(l) || l =~ /\A\*\* No matching package / }
end

Try / catch

begin
  desired = provider.latest
rescue Puppet::ExecutionFailure => e
  Puppet.err("Unparseable portversion output for #{resource[:name]}")
  desired = provider.query&.fetch(:ensure, :installed)
end

Prevention

When it happens

Trigger: ensure => latest with provider => portupgrade where portversion emits unexpected lines - warnings prepended to output, non-C locale altering messages, or a newer portversion release with different formatting. Both regexes at lib/puppet/provider/package/portupgrade.rb:119 and :149 fail to match.

Common situations: LANG/LC_ALL set to a non-C locale on the node; portupgrade suite upgraded to a version with changed output; stderr noise from pkgdb warnings mixed into output.

Related errors


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