{"record":{"id":"edb5c2cb3e9e7611","repo":"puppetlabs/puppet","slug":"the-ssl-context-and-include-system-store-parameter","errorCode":null,"errorMessage":"The ssl_context and include_system_store parameters are mutually exclusive","messagePattern":"The ssl_context and include_system_store parameters are mutually exclusive","errorType":"validation","errorClass":"Puppet::HTTP::HTTPError","httpStatus":null,"severity":"error","filePath":"lib/puppet/http/client.rb","lineNumber":473,"sourceCode":"      \"#{key}=#{Puppet::Util.uri_query_encode(value.to_s)}\"\n    end.join('&')\n  end\n\n  def elapsed(start)\n    (Time.now - start).to_f.round(3)\n  end\n\n  def raise_error(message, cause, connected)\n    if connected\n      raise Puppet::HTTP::HTTPError.new(message, cause)\n    else\n      raise Puppet::HTTP::ConnectionError.new(message, cause)\n    end\n  end\n\n  def resolve_ssl_context(ssl_context, include_system_store)\n    if ssl_context\n      raise Puppet::HTTP::HTTPError, \"The ssl_context and include_system_store parameters are mutually exclusive\" if include_system_store\n\n      ssl_context\n    elsif include_system_store\n      system_ssl_context\n    else\n      @default_ssl_context || Puppet.lookup(:ssl_context)\n    end\n  end\n\n  def system_ssl_context\n    return @default_system_ssl_context if @default_system_ssl_context\n\n    cert_provider = Puppet::X509::CertProvider.new\n    cacerts = cert_provider.load_cacerts || []\n\n    ssl = Puppet::SSL::SSLProvider.new\n    @default_system_ssl_context = ssl.create_system_context(cacerts: cacerts, include_client_cert: true)\n    ssl.print(@default_system_ssl_context)","sourceCodeStart":455,"sourceCodeEnd":491,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/http/client.rb#L455-L491","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pick one: pass ssl_context: for a custom CA chain, or include_system_store: true to also trust system roots.","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.","Audit wrapper/options-merging code for accidental propagation of both keys."],"exampleFix":"# before\nclient = Puppet::HTTP::Client.new(\n  ssl_context: custom_ctx,\n  include_system_store: true\n)\n\n# after - add the custom CA into a context that also loads system roots\nstore = OpenSSL::X509::Store.new\nstore.set_default_paths\nstore.add_file('/etc/puppet/custom_ca.pem')\nctx = OpenSSL::SSL::SSLContext.new\nctx.cert_store = store\nclient = Puppet::HTTP::Client.new(ssl_context: ctx)","handlingStrategy":"validation","validationCode":"raise ArgumentError, 'ssl_context and include_system_store are exclusive' if ssl_context && include_system_store\nclient = Puppet::HTTP::Client.new(ssl_context: ssl_context, include_system_store: include_system_store)","typeGuard":"exclusive_ok = ->(opts) { !(opts.key?(:ssl_context) && opts[:ssl_context] && opts[:include_system_store]) }\nraise ArgumentError unless exclusive_ok.call(options)","tryCatchPattern":"begin\n  Puppet::HTTP::Client.new(**opts)\nrescue Puppet::HTTP::HTTPError => e\n  raise unless e.message.include?('mutually exclusive')\n  opts = opts.slice(:ssl_context)\n  Puppet::HTTP::Client.new(**opts)\nend","preventionTips":["Choose one SSL trust strategy per client: custom context or system store.","When merging option hashes from multiple sources, reject conflicting keys explicitly."],"tags":["puppet","http","ssl","tls","mutually-exclusive","options"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}