puppetlabs/puppet · error · ArgumentError

Provider %{provider} must have features '%{needed_feature}'

Error message

Provider %{provider} must have features '%{needed_feature}' to set '%{property}' to '%{value}'

What it means

newvalue entries may declare :required_features; when the property validates a should-value it calls validate_features_per_value, which asks the resource's provider whether it satisfies those features (provider.satisfies?). If not, ArgumentError is raised naming the provider class, the required features, the property and the offending value, so the run fails instead of silently sending a request the provider cannot honour.

Source

Thrown at lib/puppet/property.rb:595

  #
  def unsafe_validate(value)
    super
    validate_features_per_value(value)
  end

  # Asserts that all required provider features are present for the given property value.
  # @raise [ArgumentError] if a required feature is not present
  # @return [void]
  # @api private
  #
  def validate_features_per_value(value)
    features = self.class.value_option(self.class.value_name(value), :required_features)
    if features
      features = Array(features)
      needed_features = features.collect(&:to_s).join(", ")
      unless provider.satisfies?(features)
        # TRANSLATORS 'Provider' refers to a Puppet provider class
        raise ArgumentError, _("Provider %{provider} must have features '%{needed_features}' to set '%{property}' to '%{value}'") %
                             { provider: provider.class.name, needed_features: needed_features, property: self.class.name, value: value }
      end
    end
  end

  # @return [Object, nil] Returns the wanted _(should)_ value of this property.
  def value
    should
  end

  # (see #should=)
  def value=(values)
    self.should = values
  end
end

View on GitHub (pinned to e227c27540)

Solutions

  1. Declare and implement the feature on the provider: has_features :mountable in the provider class.
  2. Make the capable provider win suitability: check confine, commands and defaultfor on the provider.
  3. Change the manifest not to set that value on hosts whose provider lacks the feature.

Example fix

# before (provider)
Puppet::Type.type(:mount).provide(:generic) do
  # no has_features :mountable -> setting 'mounted' raises ArgumentError
end

# after
Puppet::Type.type(:mount).provide(:generic) do
  has_features :mountable
  # ... implement mount/umount ...
end
Defensive patterns

Strategy: validation

Validate before calling

# before assigning a feature-gated value
required = [:mountable]
unless resource.provider.satisfies?(required)
  fail "provider #{resource.provider.class.name} lacks #{required.join(', ')}; cannot set #{value}"
end

Try / catch

begin
  property.should = value
rescue ArgumentError => e
  raise unless e.message =~ /must have features/
  Puppet.warning("#{e.message}; skipping #{property.name}")
end

Prevention

When it happens

Trigger: A custom type declares newvalue(:mounted, :required_features => :mountable) but the selected provider does not declare has_features :mountable; provider suitability falls back to a generic provider on some hosts; the feature name changed between module versions.

Common situations: Provider confinement (os, commands) selecting a base provider on unexpected platforms; features declared on one provider while the manifest runs against another; modules assuming capabilities the installed provider lacks.

Related errors


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