apple/pkl · error · HttpClientException
cannotParseCertFile
cannotParseCertFile
Error message
cannotParseCertFile: ${source}: ${reason} What it means
Pkl could not parse the certificate source as X.509 while peeking/reading it; an IOException occurred during CertificateFactory parsing and its root reason is reported. This variant fires when the parse stream itself raises an I/O error for the given source (file path or "<unavailable>" for inline bytes).
Source
Thrown at pkl-core/src/main/java/org/pkl/core/http/JdkHttpClient.java:190
return certificates;
}
private static void collectCertificates(
ArrayList<Certificate> anchors,
CertificateFactory factory,
InputStream stream,
Object source) {
var input = new PushbackInputStream(stream);
try {
var peekByte = input.read();
if (peekByte == -1) {
throw new HttpClientException(ErrorMessages.create("emptyCertFile", source));
} else {
input.unread(peekByte);
}
} catch (IOException e) {
throw new HttpClientException(
ErrorMessages.create("cannotParseCertFile", source, Exceptions.getRootReason(e)));
}
var first = true;
while (true) {
try {
anchors.add(factory.generateCertificate(input));
} catch (CertificateException e) {
if (e.getCause() instanceof IOException ioExc) {
if (Objects.equals(ioExc.getMessage(), "Empty input")) {
if (first) {
throw new HttpClientException(
ErrorMessages.create("cannotParseCertFile", source, "No certificate data found"));
}
break;
}
if (Objects.equals(ioExc.getMessage(), "Duplicate extensions not allowed")) continue;
}View on GitHub (pinned to f3efcbfc9b)
Solutions
- Read the `${reason}` in the message and address the underlying I/O problem.
- Re-obtain the certificate file; replace truncated or corrupted copies.
- Verify the file is a valid PEM or DER certificate using `openssl x509 -in <file> -noout`.
- Ensure no other process is concurrently writing the certificate file while Pkl reads it.
Example fix
// before (shell) $ openssl x509 -in broken-ca.pem -noout Error: unable to load certificate // after (shell) $ curl -fsSLO https://ca.example.com/ca.pem && openssl x509 -in ca.pem -noout
Defensive patterns
Strategy: try-catch
Validate before calling
try (InputStream in = Files.newInputStream(certPath)) {
CertificateFactory.getInstance("X.509").generateCertificate(in); // fail fast
} catch (Exception e) {
throw new IllegalStateException("Pre-validation failed: " + e.getMessage(), e);
} Try / catch
try {
// use the HTTP client
} catch (HttpClientException e) {
if (e.getMessage().startsWith("cannotParseCertFile")) {
// replace the certificate file and retry
}
} Prevention
- Pre-validate certificates with `openssl x509 -noout` before deployment.
- Never share a certificate file between concurrent writers and readers.
- Re-download certs rather than repairing truncated files.
- Keep certificate bundles in versioned, immutable artifacts.
When it happens
Trigger: During collectCertificates, an IOException escapes the certificate parsing loop or the initial peek; the source label (file path or "<unavailable>") and root IO reason are interpolated. Happens with corrupted reads or streams that fail mid-parse.
Common situations: Partially written or truncated certificate file that fails mid-stream, unreadable blocks on a failing disk, or inline certificate bytes that wrap a broken stream.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- cannotReadCertFile
- cannotFindCertFile
- emptyCertFile
- Failed to parse hostname in no-proxy rule: ${repr}
- (request was rewritten: %s -> %s)
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/e27289ed764c3bea.
Report an issue: GitHub.