apple/pkl · error · HttpClientException

cannotInitHttpClient

cannotInitHttpClient

Error message

cannotInitHttpClient: ${reason}

What it means

createSslContext builds the SSLContext used by the JDK HTTP client from configured trusted certificates. If gathering certificates or initializing SSLContext fails (GeneralSecurityException or IOException), it throws HttpClientException with code 'cannotInitHttpClient' carrying the root reason. The HTTP client cannot be constructed at all.

Solutions

  1. Check the root reason in the message: fix the specific certificate path/format problem
  2. Verify each certificate file exists, is readable, and is a valid PEM/DER X.509 cert (openssl x509 -in file -noout)
  3. Regenerate or re-export the certificate in a supported format
  4. Ensure the JVM has the TLS security providers available (full JDK, not a stripped runtime)

Example fix

// before
settings.setCertificateFiles(List.of(Path.of("/etc/certs/ca.pem.txt"))); // wrong file
// after
settings.setCertificateFiles(List.of(Path.of("/etc/certs/internal-ca.pem")));
Defensive patterns

Strategy: validation

Validate before calling

void validateCertificates(List<Path> files) throws IOException {
  for (Path f : files) {
    if (!Files.isRegularFile(f) || !Files.isReadable(f))
      throw new IOException("Certificate file missing or unreadable: " + f);
    // optional: parse to confirm valid X.509
    CertificateFactory.getInstance("X.509").generateCertificate(Files.newInputStream(f));
  }
}

Try / catch

try {
  var client = JdkHttpClient.create(settings); // triggers createSslContext
} catch (HttpClientException e) {
  if (e.getMessage().startsWith("cannotInitHttpClient")) {
    // inspect root reason; fix certificate paths/formats or JVM security providers
  }
}

Prevention

When it happens

Trigger: Passing certificateFiles/certificateBytes that don't exist, are unreadable, or aren't valid X.509/PKCS formats, or a JVM security-provider failure during SSLContext.getInstance("TLS")/init.

Common situations: Typo in certificate file path, PEM vs DER format confusion, corrupt certificate files, missing crypto providers in stripped-down JREs, permission issues reading cert files.

Related errors


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

Appendix: source

Thrown at pkl-core/src/main/java/org/pkl/core/http/JdkHttpClient.java:150

        return SSLContext.getDefault();
      }

      var certFactory = CertificateFactory.getInstance("X.509");
      List<Certificate> certs = gatherCertificates(certFactory, certificateFiles, certificateBytes);
      var keystore = KeyStore.getInstance(KeyStore.getDefaultType());
      keystore.load(null);
      for (var i = 0; i < certs.size(); i++) {
        keystore.setCertificateEntry("Certificate" + i, certs.get(i));
      }
      var trustManagerFactory = TrustManagerFactory.getInstance("PKIX");
      trustManagerFactory.init(keystore);

      var sslContext = SSLContext.getInstance("TLS");
      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) {

View on GitHub (pinned to f3efcbfc9b)