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

  1. 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).
  2. Read the `${reason}` in the message to identify the root cause; fix that underlying OS/IO issue.
  3. Verify the file is on a mounted, available filesystem (not an unmounted volume).
  4. 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

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


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