puppetlabs/puppet · error · Puppet::Error

Provider %{name} package command is not functional on this h

Error message

Provider %{name} package command is not functional on this host

What it means

Targetable providers (those with an optional command attribute, like the gem family) validate suitability lazily in validate_command; when the resolved command is nil - neither the resource's command attribute nor the provider's provider_command is set - the provider raises 'package command is not functional on this host'. For puppetserver_gem this means the puppetserver binary is unavailable on the node yet the resource still selected that provider.

Source

Thrown at lib/puppet/provider/package_targetable.rb:58

      end
    end
    package_commands
  end

  # Returns the resource command or provider command.

  def resource_or_provider_command
    resource.original_parameters[:command] || self.class.provider_command
  end

  # Targetable providers use has_command/is_optional to defer validation of provider suitability.
  # Evaluate provider suitability here and now by validating that the command is defined and exists.
  #
  # cmd: the full path to the package command.

  def self.validate_command(cmd)
    unless cmd
      raise Puppet::Error, _("Provider %{name} package command is not functional on this host") % { name: name }
    end
    unless File.file?(cmd)
      raise Puppet::Error, _("Provider %{name} package command '%{cmd}' does not exist on this host") % { name: name, cmd: cmd }
    end
  end

  # Return information about the package, its provider, and its (optional) command.

  def to_s
    cmd = resource[:command] || :default
    "#{@resource}(provider=#{self.class.name})(command=#{cmd})"
  end
end

View on GitHub (pinned to e227c27540)

Solutions

  1. Remove the hard-coded provider => puppetserver_gem and let provider confinement select correctly per node
  2. If the node genuinely needs it, install the prerequisite (puppetserver package providing the binary and the hocon feature)
  3. Set command => '<absolute path>' on the resource when the binary exists at a non-default location
  4. Gate the resources on the node's role or facts (e.g. $facts['pe_server_version']) in the profile

Example fix

// before - forced provider on nodes that lack puppetserver
package { 'deep_merge':
  ensure   => installed,
  provider => puppetserver_gem,
}
// after - only on actual puppetserver nodes
if $facts['pe_server_version'] {
  package { 'deep_merge':
    ensure   => installed,
    provider => puppetserver_gem,
  }
}
Defensive patterns

Strategy: validation

Validate before calling

# Ruby: ensure the targetable provider has a usable command before catalog application
def provider_command_usable?(provider_class)
  cmd = provider_class.provider_command
  !cmd.nil? && File.file?(cmd)
end

Type guard

# True when the resource does not force a command path the host lacks
def targetable_resource_ready?(resource)
  cmd = resource[:command]
  cmd.nil? || File.file?(cmd)
end

Prevention

When it happens

Trigger: Declaring provider => puppetserver_gem on a host where /opt/puppetlabs/bin/puppetserver is missing or its confines (hocon feature, non-FIPS) failed so provider_command resolves nil; explicitly setting command => undef on a targetable gem resource.

Common situations: Applying a Puppet Server gem profile to non-server nodes; hiera data forcing the provider fleet-wide; puppetserver package removed during decommissioning while the catalog still manages its gems.

Related errors


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