puppetlabs/puppet · error · ArgumentError

Expected an instance of Puppet::SSL::Verifier but was passed

Error message

Expected an instance of Puppet::SSL::Verifier but was passed a %{klass}

What it means

When use_ssl is true, the connection requires its verifier option to be an instance of Puppet::SSL::Verifier; anything else (nil, an OpenSSL object, a Puppet 4 VerifierWrapper, a custom class) raises ArgumentError naming the actual class. The verifier bundles the hostname and SSLContext used to verify the peer during TLS, so a stand-in object cannot be accepted.

Source

Thrown at lib/puppet/network/http/connection.rb:55

  #   any verification to do on the connection
  # @option options [Integer] :redirect_limit the number of allowed
  #   redirections, defaults to 10 passing any other option in the options
  #   hash results in a Puppet::Error exception
  #
  # @note the HTTP connection itself happens lazily only when {#request}, or
  #   one of the {#get}, {#post}, {#delete}, {#head} or {#put} is called
  # @note The correct way to obtain a connection is to use one of the factory
  #   methods on {Puppet::Network::HttpPool}
  # @api private
  def initialize(host, port, options = {})
    unknown_options = options.keys - OPTION_DEFAULTS.keys
    raise Puppet::Error, _("Unrecognized option(s): %{opts}") % { opts: unknown_options.map(&:inspect).sort.join(', ') } unless unknown_options.empty?

    options = OPTION_DEFAULTS.merge(options)
    @use_ssl = options[:use_ssl]
    if @use_ssl
      unless options[:verifier].is_a?(Puppet::SSL::Verifier)
        raise ArgumentError, _("Expected an instance of Puppet::SSL::Verifier but was passed a %{klass}") % { klass: options[:verifier].class }
      end

      @verifier = options[:verifier]
    end
    @redirect_limit = options[:redirect_limit]
    @site = Puppet::HTTP::Site.new(@use_ssl ? 'https' : 'http', host, port)
    @client = Puppet.runtime[:http]
  end

  # The address to connect to.
  def address
    @site.host
  end

  # The port to connect to.
  def port
    @site.port
  end

View on GitHub (pinned to e227c27540)

Solutions

  1. Create and pass a real verifier: Puppet::SSL::Verifier.new(host, ssl_context)
  2. Obtain the ssl_context from the SSL provider (e.g. Puppet::SSL::SSLProvider) rather than building OpenSSL objects manually
  3. Migrate to Puppet.runtime[:http], which constructs verifiers internally
  4. Ensure verifier is passed whenever use_ssl is true (it defaults to true)

Example fix

# before: raw SSLContext passed as verifier
conn = Puppet::Network::HTTP::Connection.new('puppet', 8140,
                                             use_ssl: true, verifier: my_ssl_context)

# after
verifier = Puppet::SSL::Verifier.new('puppet', Puppet.lookup(:ssl_context))
conn = Puppet::Network::HTTP::Connection.new('puppet', 8140,
                                             use_ssl: true, verifier: verifier)
Defensive patterns

Strategy: type-guard

Type guard

def ssl_verifier?(obj)
  obj.is_a?(Puppet::SSL::Verifier)
end

raise ArgumentError, 'verifier must be Puppet::SSL::Verifier' unless ssl_verifier?(verifier)

Prevention

When it happens

Trigger: Constructing the connection with use_ssl: true (the default) but omitting verifier; passing an OpenSSL::SSL::SSLContext or a Puppet::SSL::VerifierWrapper directly; handing in a hand-rolled duck-typed verifier object.

Common situations: Upgrades from Puppet 4 where verification used ':verify => false' or verifier factories; code that builds its own SSLContext and passes it where a verifier is expected; constructor signatures copied without the verifier argument.

Understand the failure class

Related errors


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