{"record":{"id":"89aec4e803f475e5","repo":"quarkusio/quarkus","slug":"failure-to-create-a-certificate","errorCode":null,"errorMessage":"Failure to create a certificate","messagePattern":"Failure to create a certificate","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions/tls-registry/cli/src/main/java/io/quarkus/tls/cli/letsencrypt/LetsEncryptHelpers.java","lineNumber":259,"sourceCode":"    }\n\n    private static JsonObject readAccountJson(File letsEncryptPath) {\n        LOGGER.debugf(\"Reading account information from %s\", letsEncryptPath);\n        java.nio.file.Path accountPath = Paths.get(letsEncryptPath + \"/account.json\");\n        try (FileInputStream fis = new FileInputStream(accountPath.toString())) {\n            return new JsonObject(new String(fis.readAllBytes(), StandardCharsets.US_ASCII));\n        } catch (IOException e) {\n            throw new RuntimeException(\"Unable to read the account file, you must create account first\");\n        }\n    }\n\n    private static X509Certificate getCertificate(String encodedCert) {\n        try {\n            byte[] encodedBytes = Base64.getDecoder().decode(encodedCert);\n            return (X509Certificate) CertificateFactory.getInstance(\"X.509\")\n                    .generateCertificate(new ByteArrayInputStream(encodedBytes));\n        } catch (Exception ex) {\n            throw new RuntimeException(\"Failure to create a certificate\", ex);\n        }\n    }\n\n    private static PrivateKey getPrivateKey(String encodedKey, String keyAlgorithm) {\n        try {\n            KeyFactory f = KeyFactory.getInstance((keyAlgorithm == null || \"RSA\".equals(keyAlgorithm) ? \"RSA\" : \"EC\"));\n            byte[] encodedBytes = Base64.getDecoder().decode(encodedKey);\n            PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(encodedBytes);\n            return f.generatePrivate(spec);\n        } catch (Exception ex) {\n            throw new RuntimeException(\"Failure to create a private key\", ex);\n        }\n    }\n\n    public static void renewCertificate(AcmeClient acmeClient,\n            File letsEncryptPath,\n            boolean staging,\n            String domain,","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/tls-registry/cli/src/main/java/io/quarkus/tls/cli/letsencrypt/LetsEncryptHelpers.java#L241-L277","documentation":"LetsEncryptHelpers.getCertificate() decodes a base64-encoded certificate and parses it via CertificateFactory X.509. Any exception during decoding or parsing (malformed base64, empty input, not a valid X.509 structure) is wrapped in this RuntimeException. It signals that data retrieved from the Let's Encrypt/ACME order could not be turned into a usable X509Certificate.","triggerScenarios":"getCertificate(encodedCert) throws when the encoded string is not valid base64 (IllegalArgumentException), is empty/null, or CertificateFactory.generateCertificate fails because the bytes are not a DER/PEM X.509 certificate. Called from privateKey()/certificate() accessors during certificate renewal.","commonSituations":"The downloaded ACME certificate chain file is truncated, HTML error page saved instead of cert, PEM headers ('-----BEGIN CERTIFICATE-----') left in the base64 string, or an interrupted download corrupted the stored cert file.","solutions":["Inspect the source file/URL the encoded certificate came from and re-download it; verify the file starts with valid base64 payload","Strip PEM headers/footers and whitespace before passing the string, or decode PEM body only","Validate the base64 string decodes and parses offline (openssl x509) before feeding it to the helper","Delete the stale file under the letsencrypt directory and run renewal again so ACME issues a fresh certificate"],"exampleFix":"// before\nX509Certificate cert = LetsEncryptHelpers.getCertificate(rawPemWithHeaders);\n// after\nString b64 = rawPemWithHeaders.replaceAll(\"-----BEGIN CERTIFICATE-----|-----END CERTIFICATE-----|\\\\s\", \"\");\nX509Certificate cert = LetsEncryptHelpers.getCertificate(b64);","handlingStrategy":"validation","validationCode":"static boolean looksLikeValidCertBase64(String s) {\n    if (s == null || s.isBlank()) return false;\n    try {\n        byte[] der = Base64.getDecoder().decode(s.replaceAll(\"-----[A-Z ]+-----|\\\\s\", \"\"));\n        CertificateFactory.getInstance(\"X.509\").generateCertificate(new ByteArrayInputStream(der));\n        return true;\n    } catch (Exception e) { return false; }\n}","typeGuard":"if (raw == null || raw.isBlank() || !looksLikeValidCertBase64(raw)) { reissueOrAbort(); }","tryCatchPattern":"try {\n    X509Certificate cert = LetsEncryptHelpers.getCertificate(encoded);\n} catch (RuntimeException e) {\n    LOGGER.error(\"Corrupted certificate payload; delete stored cert and renew\", e);\n    renewCertificate();\n}","preventionTips":["Strip PEM headers/footers and whitespace before decoding","Validate stored cert with openssl x509 after each renewal","Re-download the certificate rather than reusing a possibly truncated file","Check disk space and download completion (HTTP status) before persisting"],"tags":["certificate","base64","acme","tls"],"backgroundTag":"invalid-certificate-parsing","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}