apple/pkl · error · CliException

Could not find bundled certificates

Error message

Could not find bundled certificates

What it means

CliCommand falls back to a CA root certificate bundle (PklCARoots.pem) embedded as a classpath resource when no CA certs directory is configured. This error means the bundle resource could not be found on the classpath, so TLS trust cannot be set up. It indicates a broken/trimmed build artifact or an unusual classloader that cannot see the resource.

Solutions

  1. Verify org/pkl/commons/cli/PklCARoots.pem exists inside the jar: unzip -l app.jar | grep PklCARoots; if missing, rebuild or re-download the distribution unmodified.
  2. Provide CA certificates explicitly so the fallback is never used: set the CA certs directory option (e.g. --ca-certificates or PKL_CA_CERTIFICATES_DIR) to a directory of PEM files.
  3. If using shading/proguard, add a keep/include rule for org/pkl/commons/cli/*.pem resources.
  4. Check for a custom classloader that cannot see the resource; run with the standard classloader.

Example fix

// before
java -jar pkl.jar eval // fails on stripped jar
// after
export PKL_CA_CERTIFICATES_DIR=/etc/ssl/certs
java -jar pkl.jar eval
Defensive patterns

Strategy: fallback

Validate before calling

val pem = CliCommand::class.java.classLoader.getResourceAsStream("org/pkl/commons/cli/PklCARoots.pem")
requireNotNull(pem) { "bundled PklCARoots.pem missing from classpath; set CA certs dir instead" }

Type guard

fun hasBundledCerts(): Boolean =
  CliCommand::class.java.classLoader.getResource("org/pkl/commons/cli/PklCARoots.pem") != null

Try / catch

try {
  runCommand()
} catch (e: CliException) {
  if (e.message?.contains("bundled certificates") == true) {
    // rebuild distribution or set CA certs directory and retry
  } else throw e
}

Prevention

When it happens

Trigger: Running a CLI command that needs an HTTP client when (1) no CA certificates directory is set, and (2) classLoader.getResourceAsStream("org/pkl/commons/cli/PklCARoots.pem") returns null — e.g. the pem was stripped from the jar, a shaded/proguarded build excluded resources, or a custom classloader is in use.

Common situations: Deploying a repackaged jar that omitted resource files; running tests with a filtered classpath; using a module system or fat-jar plugin that excludes .pem resources; corporate environment where devs expected to point at a custom CA dir but left it unset on a broken distribution.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/e9a5c00406bce404. Report an issue: GitHub.

Appendix: source

Thrown at pkl-commons-cli/src/main/kotlin/org/pkl/commons/cli/CliCommand.kt:237

  private fun HttpClient.Builder.addDefaultCliCertificates() {
    val caCertsDir = IoUtils.getSystemCaCertsDir()
    var certsAdded = false
    if (Files.isDirectory(caCertsDir)) {
      Files.list(caCertsDir)
        .filter { it.isRegularFile() && !it.fileName.toString().startsWith(".") }
        .forEach { cert ->
          certsAdded = true
          addCertificates(cert)
        }
    }
    if (certsAdded) {
      DebugLogger.log("Loading CA certificates from ${caCertsDir.normalize().absolutePathString()}")
    } else {
      DebugLogger.log("Using built-in CA certificates")
      val defaultCerts =
        this@CliCommand.javaClass.classLoader.getResourceAsStream(
          "org/pkl/commons/cli/PklCARoots.pem"
        ) ?: throw CliException("Could not find bundled certificates")
      addCertificates(defaultCerts.readAllBytes())
    }
  }

  /**
   * The HTTP client used for this command.
   *
   * To release resources held by the HTTP client in a timely manner, call [HttpClient.close].
   */
  val httpClient: HttpClient by lazy {
    with(HttpClient.builder()) {
      setTestPort(cliOptions.testPort)
      if (cliOptions.normalizedCaCertificates.isEmpty()) {
        addDefaultCliCertificates()
      } else {
        for (file in cliOptions.normalizedCaCertificates) addCertificates(file)
      }
      if ((proxyAddress ?: noProxy) != null) {

View on GitHub (pinned to f3efcbfc9b)