{"record":{"id":"98ff64de448d77aa","repo":"puppetlabs/puppet","slug":"the-crl-is-missing-from-path","errorCode":null,"errorMessage":"The CRL is missing from '%{path}'","messagePattern":"The CRL is missing from '%(.+?)'","errorType":"exception","errorClass":"Puppet::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/x509/cert_provider.rb","lineNumber":107,"sourceCode":"  # @api private\n  def save_crls(crls)\n    save_pem(crls.map(&:to_pem).join, @crlpath, **permissions_for_setting(:hostcrl))\n  rescue SystemCallError => e\n    raise Puppet::Error.new(_(\"Failed to save CRLs to '%{crlpath}'\") % { crlpath: @crlpath }, e)\n  end\n\n  # Load CRLs from the configured `crlpath` path.\n  #\n  # @param required [Boolean] If true, raise if they are missing\n  # @return (see #load_crls_from_pem)\n  # @raise (see #load_crls_from_pem)\n  # @raise [Puppet::Error] if the CRLs cannot be loaded\n  #\n  # @api private\n  def load_crls(required: false)\n    pem = load_pem(@crlpath)\n    if !pem && required\n      raise Puppet::Error, _(\"The CRL is missing from '%{path}'\") % { path: @crlpath }\n    end\n\n    pem ? load_crls_from_pem(pem) : nil\n  rescue SystemCallError => e\n    raise Puppet::Error.new(_(\"Failed to load CRLs from '%{crlpath}'\") % { crlpath: @crlpath }, e)\n  end\n\n  # Load PEM encoded CRL(s).\n  #\n  # @param pem [String] PEM encoded CRL(s)\n  # @return [Array<OpenSSL::X509::CRL>] Array of CRLs\n  # @raise [OpenSSL::X509::CRLError] The `pem` text does not contain a valid CRL\n  #\n  # @api private\n  def load_crls_from_pem(pem)\n    # TRANSLATORS 'PEM' is an acronym and shouldn't be translated\n    raise OpenSSL::X509::CRLError, _(\"Failed to parse CRLs as PEM\") if pem !~ CRL_DELIMITERS\n","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/x509/cert_provider.rb#L89-L125","documentation":"Raised by CertProvider#load_crls when required is true and no PEM data can be read from @crlpath (Puppet[:hostcrl], default ssldir/crl/crl.pem). Puppet loads the CRL whenever certificate_revocation is enabled (the default), so a missing CRL blocks SSL context creation even though the CA cert and client cert are fine.","triggerScenarios":"SSLProvider#load_context with certificate_revocation enabled on a host whose crl.pem was never fetched or was deleted; ssldir cloned/migrated incompletely (ca.pem copied, crl.pem not). Direct call: load_crls(required: true) with the file absent or empty.","commonSituations":"Golden VM images cloned without the CRL; cleanup jobs pruning 'stale' files under ssldir; nodes provisioned by hand where only the cert chain was copied from the CA.","solutions":["Run `puppet agent -t` so the agent downloads crl.pem from the CA","Check `puppet config print hostcrl` and confirm the file exists and is non-empty","Copy the CRL from the CA (ssldir/ca/ca_crl.pem on the Puppet server) into hostcrl","If revocation checking is deliberately off, set certificate_revocation=false so the CRL is not required"],"exampleFix":"# before\n$ ls /etc/puppetlabs/puppet/ssl/crl/\n(empty)\n\n# after (on the CA node)\n$ cp /etc/puppetlabs/puppet/ssl/ca/ca_crl.pem /etc/puppetlabs/puppet/ssl/crl/crl.pem","handlingStrategy":"validation","validationCode":"crl = Puppet[:hostcrl]\nneed_crl = Puppet[:certificate_revocation]\nraise \"CRL missing at #{crl} — run `puppet agent -t`\" if need_crl && !File.size?(crl)","typeGuard":null,"tryCatchPattern":"begin\n  crls = provider.load_crls(required: true)\nrescue Puppet::Error => e\n  abort \"CRL unavailable (#{e.message}); fetch with `puppet agent -t` or disable certificate_revocation\"\nend","preventionTips":["Include crl.pem whenever ca.pem is copied or baked into images","Keep the certificate_revocation setting aligned with whether your CA publishes a CRL","Treat the whole ssldir as a unit in backup and migration jobs"],"tags":["ruby","puppet","ssl","x509","crl","revocation"],"backgroundTag":"missing-certificate-revocation-list","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}