apple/pkl · error · HttpClientException
cannotReadCertFile
cannotReadCertFile
Error message
cannotReadCertFile: ${reason} What it means
Pkl found a configured certificate file but could not read its contents, typically due to an I/O problem (permissions, transient OS error). gatherCertificates catches the IOException and surfaces the root reason via cannotReadCertFile. Unlike error 100, the file exists but reading it failed.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/http/JdkHttpClient.java:164
sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
return sslContext;
} catch (GeneralSecurityException | IOException e) {
throw new HttpClientException(
ErrorMessages.create("cannotInitHttpClient", Exceptions.getRootReason(e)), e);
}
}
private static List<Certificate> gatherCertificates(
CertificateFactory factory, List<Path> certificateFiles, List<ByteBuffer> certificateBytes) {
var certificates = new ArrayList<Certificate>();
for (var file : certificateFiles) {
try (var stream = Files.newInputStream(file)) {
collectCertificates(certificates, factory, stream, file);
} catch (NoSuchFileException e) {
throw new HttpClientException(ErrorMessages.create("cannotFindCertFile", file));
} catch (IOException e) {
throw new HttpClientException(
ErrorMessages.create("cannotReadCertFile", Exceptions.getRootReason(e)));
}
}
for (var byteBuffer : certificateBytes) {
var stream = new ByteArrayInputStream(byteBuffer.array());
collectCertificates(certificates, factory, stream, "<unavailable>");
}
return certificates;
}
private static void collectCertificates(
ArrayList<Certificate> anchors,
CertificateFactory factory,
InputStream stream,
Object source) {
var input = new PushbackInputStream(stream);
try {View on GitHub (pinned to f3efcbfc9b)
Solutions
- Check and fix file permissions so the user running Pkl can read the certificate file (e.g. `chmod 644` or add the user to the right group).
- Read the `${reason}` in the message to identify the root cause; fix that underlying OS/IO issue.
- Verify the file is on a mounted, available filesystem (not an unmounted volume).
- If running in a container, ensure the cert file is copied/mounted with readable permissions.
Example fix
// before (shell) -rw------- root root /etc/ssl/certs/custom-ca.pem # unreadable by app user // after (shell) chown root:app /etc/ssl/certs/custom-ca.pem && chmod 640 /etc/ssl/certs/custom-ca.pem
Defensive patterns
Strategy: validation
Validate before calling
Path certFile = Paths.get(caCertPath);
try (InputStream in = Files.newInputStream(certFile)) {
in.read(); // forces an actual read to surface permission/IO issues early
} catch (IOException e) {
throw new IllegalStateException("Cannot read cert file: " + e.getMessage(), e);
} Try / catch
try {
// use the HTTP client
} catch (HttpClientException e) {
if (e.getMessage().startsWith("cannotReadCertFile")) {
// check file permissions / fallback to system trust store
}
} Prevention
- Deploy certs with world/group-readable permissions appropriate to the running user.
- Avoid root-only (0600) cert files when Pkl runs as a service user.
- Verify mounted volumes are available before starting Pkl in containers.
- Check `${reason}` in logs immediately to catch permission or mount issues.
When it happens
Trigger: Files.newInputStream succeeds in opening or reading a configured certificate file but an IOException occurs; Exceptions.getRootReason(e) supplies the `${reason}`. Typical: unreadable file permissions, read-protected file, or hardware/OS read failure during gatherCertificates.
Common situations: Certificate file owned by root with 0600 while Pkl runs as another user, file unreadable inside a container, SELinux/AppArmor denial, or an NFS/network mount being unavailable.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- cannotParseCertFile
- cannotFindCertFile
- emptyCertFile
- (request was rewritten: %s -> %s)
- ioErrorLoadingModule
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/6359e664c563ab9d.
Report an issue: GitHub.