puppetlabs/puppet · error · Puppet::HTTP::HTTPError

The ssl_context and include_system_store parameters are mutu

Error message

The ssl_context and include_system_store parameters are mutually exclusive

What it means

When resolving which SSL context to use, Puppet::HTTP::Client accepts either an explicit ssl_context (a pre-built OpenSSL::SSL::SSLContext) or include_system_store: true (trust the OS CA bundle in addition), but not both — the combination is contradictory and raises Puppet::HTTP::HTTPError immediately.

Source

Thrown at lib/puppet/http/client.rb:473

      "#{key}=#{Puppet::Util.uri_query_encode(value.to_s)}"
    end.join('&')
  end

  def elapsed(start)
    (Time.now - start).to_f.round(3)
  end

  def raise_error(message, cause, connected)
    if connected
      raise Puppet::HTTP::HTTPError.new(message, cause)
    else
      raise Puppet::HTTP::ConnectionError.new(message, cause)
    end
  end

  def resolve_ssl_context(ssl_context, include_system_store)
    if ssl_context
      raise Puppet::HTTP::HTTPError, "The ssl_context and include_system_store parameters are mutually exclusive" if include_system_store

      ssl_context
    elsif include_system_store
      system_ssl_context
    else
      @default_ssl_context || Puppet.lookup(:ssl_context)
    end
  end

  def system_ssl_context
    return @default_system_ssl_context if @default_system_ssl_context

    cert_provider = Puppet::X509::CertProvider.new
    cacerts = cert_provider.load_cacerts || []

    ssl = Puppet::SSL::SSLProvider.new
    @default_system_ssl_context = ssl.create_system_context(cacerts: cacerts, include_client_cert: true)
    ssl.print(@default_system_ssl_context)

View on GitHub (pinned to e227c27540)

Solutions

  1. Pick one: pass ssl_context: for a custom CA chain, or include_system_store: true to also trust system roots.
  2. If you need both custom and system CAs, build a single SSLContext whose store contains your CA plus the default paths, and pass only ssl_context.
  3. Audit wrapper/options-merging code for accidental propagation of both keys.

Example fix

# before
client = Puppet::HTTP::Client.new(
  ssl_context: custom_ctx,
  include_system_store: true
)

# after - add the custom CA into a context that also loads system roots
store = OpenSSL::X509::Store.new
store.set_default_paths
store.add_file('/etc/puppet/custom_ca.pem')
ctx = OpenSSL::SSL::SSLContext.new
ctx.cert_store = store
client = Puppet::HTTP::Client.new(ssl_context: ctx)
Defensive patterns

Strategy: validation

Validate before calling

raise ArgumentError, 'ssl_context and include_system_store are exclusive' if ssl_context && include_system_store
client = Puppet::HTTP::Client.new(ssl_context: ssl_context, include_system_store: include_system_store)

Type guard

exclusive_ok = ->(opts) { !(opts.key?(:ssl_context) && opts[:ssl_context] && opts[:include_system_store]) }
raise ArgumentError unless exclusive_ok.call(options)

Try / catch

begin
  Puppet::HTTP::Client.new(**opts)
rescue Puppet::HTTP::HTTPError => e
  raise unless e.message.include?('mutually exclusive')
  opts = opts.slice(:ssl_context)
  Puppet::HTTP::Client.new(**opts)
end

Prevention

When it happens

Trigger: Puppet::HTTP::Client.new(ssl_context: ctx, include_system_store: true); request options that forward both keys to connection setup; wrapper code that merges example snippets into one options hash.

Common situations: Copying two different documentation examples (custom CA + system store) into one client construction; corporates proxies requiring both a custom CA and public certs, solved wrongly by passing both flags instead of building one context that chains the extra CA.

Related errors


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