{"record":{"id":"bb168d5694c30976","repo":"spring-projects/spring-boot","slug":"error-reading-certificate","errorCode":null,"errorMessage":"Error reading certificate: {}","messagePattern":"Error reading certificate: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"buildpack/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/ssl/PemCertificateParser.java","lineNumber":94,"sourceCode":"\t\tcatch (CertificateException ex) {\n\t\t\tthrow new IllegalStateException(\"Unable to get X.509 certificate factory\", ex);\n\t\t}\n\t}\n\n\tprivate static void readCertificates(String text, CertificateFactory factory, Consumer<X509Certificate> consumer) {\n\t\ttry {\n\t\t\tMatcher matcher = PATTERN.matcher(text);\n\t\t\twhile (matcher.find()) {\n\t\t\t\tString encodedText = matcher.group(1);\n\t\t\t\tbyte[] decodedBytes = decodeBase64(encodedText);\n\t\t\t\tByteArrayInputStream inputStream = new ByteArrayInputStream(decodedBytes);\n\t\t\t\twhile (inputStream.available() > 0) {\n\t\t\t\t\tconsumer.accept((X509Certificate) factory.generateCertificate(inputStream));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (CertificateException ex) {\n\t\t\tthrow new IllegalStateException(\"Error reading certificate: \" + ex.getMessage(), ex);\n\t\t}\n\t}\n\n\tprivate static byte[] decodeBase64(String content) {\n\t\tbyte[] bytes = content.replace(\"\\r\", \"\").replace(\"\\n\", \"\").getBytes();\n\t\treturn Base64.getDecoder().decode(bytes);\n\t}\n\n}\n","sourceCodeStart":76,"sourceCodeEnd":104,"githubUrl":"https://github.com/spring-projects/spring-boot/blob/270dfe353fb830fd69b823a8a859287ff103854b/buildpack/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/ssl/PemCertificateParser.java#L76-L104","documentation":"Inside PemCertificateParser.readCertificates, after the HEADER/BASE64_TEXT/FOOTER regex matches a block and decodeBase64 decodes it, factory.generateCertificate(inputStream) is called. A CertificateException means the decoded bytes are not a valid DER-encoded X.509 certificate. The wrapping IllegalStateException includes the underlying exception's message.","triggerScenarios":"The regex matched a -----BEGIN ... CERTIFICATE----- block, but the base64 body decoded to bytes that factory.generateCertificate cannot parse: truncated body, corrupted bytes, a non-X.509 object, or an OpenSSL-specific BEGIN TRUSTED CERTIFICATE block.","commonSituations":"Copy-pasting a cert and dropping the last few base64 lines; line-ending corruption (CRLF/LF mixed); a PGP or S/MIME block that happens to match the regex; an OpenSSL BEGIN TRUSTED CERTIFICATE that the X.509 factory rejects.","solutions":["Validate the file: `openssl x509 -in cert.pem -noout` (it must parse cleanly).","Re-export the certificate as a standard PEM: `openssl x509 -in cert.pem -out cert-clean.pem`.","Ensure the full BEGIN CERTIFICATE ... END CERTIFICATE block and its base64 body are intact."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate the PEM cert externally before invoking the build\nProcess p = new ProcessBuilder(\"openssl\", \"x509\", \"-in\", certPath.toString(), \"-noout\")\n        .redirectErrorStream(true).start();\nif (p.waitFor() != 0) {\n    throw new IllegalArgumentException(\"Invalid certificate at \" + certPath);\n}","typeGuard":null,"tryCatchPattern":"try {\n    PemCertificateParser.parse(text);\n} catch (IllegalStateException ex) {\n    if (ex.getCause() instanceof CertificateException\n            && ex.getMessage().startsWith(\"Error reading certificate\")) {\n        // hint: validate / re-export the PEM with openssl\n    }\n    throw ex;\n}","preventionTips":["Always re-export certificates as standard PEM (`openssl x509 -in cert.pem -out clean.pem`).","Avoid BEGIN TRUSTED CERTIFICATE blocks; use BEGIN CERTIFICATE.","Verify the full BEGIN..END block is intact when copying PEM text."],"tags":["docker","ssl","certificate","pem","buildpack"],"backgroundTag":null,"analyzedSha":"270dfe353fb830fd69b823a8a859287ff103854b","analyzedAt":"2026-08-11T19:42:06.541Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}