{"record":{"id":"b483df52b268a95d","repo":"puppetlabs/puppet","slug":"the-ca-certificates-are-missing-from-path","errorCode":null,"errorMessage":"The CA certificates are missing from '%{path}'","messagePattern":"The CA certificates are missing from '%(.+?)'","errorType":"exception","errorClass":"Puppet::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/x509/cert_provider.rb","lineNumber":60,"sourceCode":"  # @api private\n  def save_cacerts(certs)\n    save_pem(certs.map(&:to_pem).join, @capath, **permissions_for_setting(:localcacert))\n  rescue SystemCallError => e\n    raise Puppet::Error.new(_(\"Failed to save CA certificates to '%{capath}'\") % { capath: @capath }, e)\n  end\n\n  # Load CA certs from the configured `capath`.\n  #\n  # @param required [Boolean] If true, raise if they are missing\n  # @return (see #load_cacerts_from_pem)\n  # @raise (see #load_cacerts_from_pem)\n  # @raise [Puppet::Error] if the certs cannot be loaded\n  #\n  # @api private\n  def load_cacerts(required: false)\n    pem = load_pem(@capath)\n    if !pem && required\n      raise Puppet::Error, _(\"The CA certificates are missing from '%{path}'\") % { path: @capath }\n    end\n\n    pem ? load_cacerts_from_pem(pem) : nil\n  rescue SystemCallError => e\n    raise Puppet::Error.new(_(\"Failed to load CA certificates from '%{capath}'\") % { capath: @capath }, e)\n  end\n\n  # Load PEM encoded CA certificates.\n  #\n  # @param pem [String] PEM encoded certificate(s)\n  # @return [Array<OpenSSL::X509::Certificate>] Array of CA certs\n  # @raise [OpenSSL::X509::CertificateError] The `pem` text does not contain a valid cert\n  #\n  # @api private\n  def load_cacerts_from_pem(pem)\n    # TRANSLATORS 'PEM' is an acronym and shouldn't be translated\n    raise OpenSSL::X509::CertificateError, _(\"Failed to parse CA certificates as PEM\") if pem !~ CERT_DELIMITERS\n","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/x509/cert_provider.rb#L42-L78","documentation":"Raised as Puppet::Error by Puppet::X509::CertProvider#load_cacerts when required is true and no PEM data can be read from the configured CA bundle path (@capath, normally Puppet[:localcacert], e.g. /etc/puppetlabs/puppet/ssl/certs/ca.pem). Puppet refuses to build a TLS context without a trust anchor, so every HTTPS call from this node fails. In practice the node has not bootstrapped its SSL directory, or the ssldir/localcacert settings point somewhere unexpected.","triggerScenarios":"CertProvider#load_cacerts(required: true) finds no PEM at @capath. Reached indirectly through Puppet::SSL::SSLProvider#load_context and Puppet::HTTP::Client#default_ssl_context (used by puppet agent, puppet ssl, and any Puppet::HTTP call) when the CA file is absent, empty, or unreadable. Direct call: Puppet::X509::CertProvider.new.load_cacerts(required: true) with a missing file.","commonSituations":"Fresh agent or container image whose ssldir was never populated; localcacert deleted by cleanup scripts; ssldir overridden in puppet.conf so root and the service user look in different directories; cloned VMs where the ssl directory was not carried over.","solutions":["Run `puppet agent -t` (or `puppet ssl provision`) once so the agent downloads ca.pem into ssldir","Check the resolved paths: `puppet config print ssldir localcacert` and confirm ca.pem exists there and is non-empty","Copy ca.pem from the CA Puppet server (mode 0640, correct ownership) if the node cannot reach it yet","Fix wrong ssldir/localcacert settings or stale DNS/SRV records that send the agent elsewhere","If the ssl directory is unrecoverable, move it aside and re-enroll: new key, CSR, and CA-signed certificate"],"exampleFix":"// before\n$ puppet agent -t\nError: The CA certificates are missing from '/etc/puppetlabs/puppet/ssl/certs/ca.pem'\n\n// after (bootstrap once, then rerun)\n$ puppet ssl provision    # downloads ca.pem + crl.pem, submits CSR\n$ puppet agent -t","handlingStrategy":"validation","validationCode":"require 'puppet'\n\ncapath = Puppet[:localcacert]\nraise \"CA bundle missing or empty at #{capath} — run `puppet agent -t`\" unless File.size?(capath)\nraise \"CA bundle unreadable at #{capath}\" unless File.readable?(capath)","typeGuard":null,"tryCatchPattern":"begin\n  certs = provider.load_cacerts(required: true)\nrescue Puppet::Error => e\n  Puppet.err e.message            # message includes the exact capath\n  provision_ssl!                  # e.g. shell out to `puppet ssl provision`\n  certs = provider.load_cacerts(required: true)  # one retry after bootstrap\nend","preventionTips":["Bake a provisioned ssl dir (ca.pem, crl.pem) into golden images","Alert when Puppet[:localcacert] or Puppet[:hostcrl] is absent before the agent cron fires","Never repoint ssldir without migrating its contents"],"tags":["ruby","puppet","ssl","x509","ca-certificate","bootstrap"],"backgroundTag":"missing-certificate-authority","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}