{"record":{"id":"380fdfe10a05adc8","repo":"apple/pkl","slug":"emptycertfile","errorCode":"emptyCertFile","errorMessage":"emptyCertFile: ${source}","messagePattern":"emptyCertFile: (.+?)","errorType":"exception","errorClass":"HttpClientException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/http/JdkHttpClient.java","lineNumber":185,"sourceCode":"    }\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 {\n      var peekByte = input.read();\n      if (peekByte == -1) {\n        throw new HttpClientException(ErrorMessages.create(\"emptyCertFile\", source));\n      } else {\n        input.unread(peekByte);\n      }\n    } catch (IOException e) {\n      throw new HttpClientException(\n          ErrorMessages.create(\"cannotParseCertFile\", source, Exceptions.getRootReason(e)));\n    }\n\n    var first = true;\n    while (true) {\n      try {\n        anchors.add(factory.generateCertificate(input));\n      } catch (CertificateException e) {\n        if (e.getCause() instanceof IOException ioExc) {\n          if (Objects.equals(ioExc.getMessage(), \"Empty input\")) {\n            if (first) {\n              throw new HttpClientException(\n                  ErrorMessages.create(\"cannotParseCertFile\", source, \"No certificate data found\"));","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/http/JdkHttpClient.java#L167-L203","documentation":"Pkl opened a configured certificate source (file or inline bytes) and found it completely empty (zero bytes). collectCertificates peeks at the first byte and throws this error when EOF is reached immediately, since an empty stream cannot contain any certificate.","triggerScenarios":"A certificate file configured via certificateFiles has zero length, or a certificateBytes buffer is empty (array with no bytes); the PushbackInputStream.read() returns -1 in collectCertificates.","commonSituations":"A `touch`-created placeholder cert file, a truncated download that produced a 0-byte file, a config pointing at a log or lock file, or build steps that created an empty output artifact.","solutions":["Check the file size (`ls -l <path>` / `stat`); replace the empty file with a real PEM/DER certificate.","Re-download or re-export the certificate from the source CA; verify it contains PEM blocks (`-----BEGIN CERTIFICATE-----`).","If using certificateBytes, verify the byte array is populated before passing it to the client.","Fix the path if the empty file is not the intended certificate."],"exampleFix":"// before (shell)\n$ stat -c %s ca.pem\n0\n// after (shell)\n$ cp /etc/ssl/certs/ca-certificates.crt ca.pem && head -1 ca.pem\n-----BEGIN CERTIFICATE-----","handlingStrategy":"validation","validationCode":"Path certFile = Paths.get(caCertPath);\ntry {\n  if (Files.size(certFile) == 0) {\n    throw new IllegalStateException(\"Certificate file is empty: \" + certFile);\n  }\n  String head = Files.readString(certFile).strip();\n  if (!head.startsWith(\"-----BEGIN\")) {\n    throw new IllegalStateException(\"Not a PEM certificate: \" + certFile);\n  }\n} catch (IOException e) {\n  throw new IllegalStateException(\"Cannot inspect cert file\", e);\n}","typeGuard":null,"tryCatchPattern":"try {\n  // configure HTTP client\n} catch (HttpClientException e) {\n  if (e.getMessage().startsWith(\"emptyCertFile\")) {\n    // re-fetch or substitute a valid certificate\n  }\n}","preventionTips":["Check file sizes after downloading certificates (a 0-byte file means a failed download).","Validate PEM content before wiring files into configuration.","Avoid placeholder files created by touch in config directories.","Verify downloaded artifacts with checksums."],"tags":["http","tls","empty-file","configuration"],"backgroundTag":"empty-required-field","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"}