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
- 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.
- 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.
- If using shading/proguard, add a keep/include rule for org/pkl/commons/cli/*.pem resources.
- 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
- Always ship the original, unmodified jar/distribution; do not strip .pem resources when shading.
- In restricted network environments, configure the CA certificates directory explicitly instead of relying on the bundle.
- Smoke-test CLI commands that make HTTPS calls in CI to catch broken artifacts early.
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.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Cannot download packages because no cache directory is…
- Cannot generate documentation for just one module within a…
- Cannot generate JUnit report for $moduleUri. A report with…
- Cannot substitute output path placeholder
- Cannot write to stdin
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)