puppetlabs/puppet · error · Puppet::Error

The CA certificates are missing from '%{path}'

Error message

The CA certificates are missing from '%{path}'

What it means

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.

Source

Thrown at lib/puppet/x509/cert_provider.rb:60

  # @api private
  def save_cacerts(certs)
    save_pem(certs.map(&:to_pem).join, @capath, **permissions_for_setting(:localcacert))
  rescue SystemCallError => e
    raise Puppet::Error.new(_("Failed to save CA certificates to '%{capath}'") % { capath: @capath }, e)
  end

  # Load CA certs from the configured `capath`.
  #
  # @param required [Boolean] If true, raise if they are missing
  # @return (see #load_cacerts_from_pem)
  # @raise (see #load_cacerts_from_pem)
  # @raise [Puppet::Error] if the certs cannot be loaded
  #
  # @api private
  def load_cacerts(required: false)
    pem = load_pem(@capath)
    if !pem && required
      raise Puppet::Error, _("The CA certificates are missing from '%{path}'") % { path: @capath }
    end

    pem ? load_cacerts_from_pem(pem) : nil
  rescue SystemCallError => e
    raise Puppet::Error.new(_("Failed to load CA certificates from '%{capath}'") % { capath: @capath }, e)
  end

  # Load PEM encoded CA certificates.
  #
  # @param pem [String] PEM encoded certificate(s)
  # @return [Array<OpenSSL::X509::Certificate>] Array of CA certs
  # @raise [OpenSSL::X509::CertificateError] The `pem` text does not contain a valid cert
  #
  # @api private
  def load_cacerts_from_pem(pem)
    # TRANSLATORS 'PEM' is an acronym and shouldn't be translated
    raise OpenSSL::X509::CertificateError, _("Failed to parse CA certificates as PEM") if pem !~ CERT_DELIMITERS

View on GitHub (pinned to e227c27540)

Solutions

  1. Run `puppet agent -t` (or `puppet ssl provision`) once so the agent downloads ca.pem into ssldir
  2. Check the resolved paths: `puppet config print ssldir localcacert` and confirm ca.pem exists there and is non-empty
  3. Copy ca.pem from the CA Puppet server (mode 0640, correct ownership) if the node cannot reach it yet
  4. Fix wrong ssldir/localcacert settings or stale DNS/SRV records that send the agent elsewhere
  5. If the ssl directory is unrecoverable, move it aside and re-enroll: new key, CSR, and CA-signed certificate

Example fix

// before
$ puppet agent -t
Error: The CA certificates are missing from '/etc/puppetlabs/puppet/ssl/certs/ca.pem'

// after (bootstrap once, then rerun)
$ puppet ssl provision    # downloads ca.pem + crl.pem, submits CSR
$ puppet agent -t
Defensive patterns

Strategy: validation

Validate before calling

require 'puppet'

capath = Puppet[:localcacert]
raise "CA bundle missing or empty at #{capath} — run `puppet agent -t`" unless File.size?(capath)
raise "CA bundle unreadable at #{capath}" unless File.readable?(capath)

Try / catch

begin
  certs = provider.load_cacerts(required: true)
rescue Puppet::Error => e
  Puppet.err e.message            # message includes the exact capath
  provision_ssl!                  # e.g. shell out to `puppet ssl provision`
  certs = provider.load_cacerts(required: true)  # one retry after bootstrap
end

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


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