{"record":{"id":"6359e664c563ab9d","repo":"apple/pkl","slug":"cannotreadcertfile","errorCode":"cannotReadCertFile","errorMessage":"cannotReadCertFile: ${reason}","messagePattern":"cannotReadCertFile: (.+?)","errorType":"exception","errorClass":"HttpClientException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/http/JdkHttpClient.java","lineNumber":164,"sourceCode":"      sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());\n\n      return sslContext;\n    } catch (GeneralSecurityException | IOException e) {\n      throw new HttpClientException(\n          ErrorMessages.create(\"cannotInitHttpClient\", Exceptions.getRootReason(e)), e);\n    }\n  }\n\n  private static List<Certificate> gatherCertificates(\n      CertificateFactory factory, List<Path> certificateFiles, List<ByteBuffer> certificateBytes) {\n    var certificates = new ArrayList<Certificate>();\n    for (var file : certificateFiles) {\n      try (var stream = Files.newInputStream(file)) {\n        collectCertificates(certificates, factory, stream, file);\n      } catch (NoSuchFileException e) {\n        throw new HttpClientException(ErrorMessages.create(\"cannotFindCertFile\", file));\n      } catch (IOException e) {\n        throw new HttpClientException(\n            ErrorMessages.create(\"cannotReadCertFile\", Exceptions.getRootReason(e)));\n      }\n    }\n    for (var byteBuffer : certificateBytes) {\n      var stream = new ByteArrayInputStream(byteBuffer.array());\n      collectCertificates(certificates, factory, stream, \"<unavailable>\");\n    }\n    return certificates;\n  }\n\n  private static void collectCertificates(\n      ArrayList<Certificate> anchors,\n      CertificateFactory factory,\n      InputStream stream,\n      Object source) {\n    var input = new PushbackInputStream(stream);\n\n    try {","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/http/JdkHttpClient.java#L146-L182","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (shell)\n-rw------- root root /etc/ssl/certs/custom-ca.pem   # unreadable by app user\n// after (shell)\nchown root:app /etc/ssl/certs/custom-ca.pem && chmod 640 /etc/ssl/certs/custom-ca.pem","handlingStrategy":"validation","validationCode":"Path certFile = Paths.get(caCertPath);\ntry (InputStream in = Files.newInputStream(certFile)) {\n  in.read(); // forces an actual read to surface permission/IO issues early\n} catch (IOException e) {\n  throw new IllegalStateException(\"Cannot read cert file: \" + e.getMessage(), e);\n}","typeGuard":null,"tryCatchPattern":"try {\n  // use the HTTP client\n} catch (HttpClientException e) {\n  if (e.getMessage().startsWith(\"cannotReadCertFile\")) {\n    // check file permissions / fallback to system trust store\n  }\n}","preventionTips":["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."],"tags":["http","tls","io","permissions"],"backgroundTag":"file-read-failed","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}