{"record":{"id":"753ae4bdc21a26aa","repo":"quarkusio/quarkus","slug":"invalid-pem-file-no-pem-content-found","errorCode":null,"errorMessage":"Invalid PEM file: No PEM content found.","messagePattern":"Invalid PEM file: No PEM content found\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"extensions/tls-registry/cli/src/main/java/io/quarkus/tls/cli/letsencrypt/LetsEncryptHelpers.java","lineNumber":69,"sourceCode":"\n        AUDIT.debug(\"Writing certificate chain to file: \" + certificateChainFile.getAbsolutePath());\n\n        if (chain.length == 1) {\n            CertificateUtils.writeCertificateToPEM(chain[0], certificateChainFile);\n            return;\n        }\n\n        // For some reason the method from CertificateUtils distinguishes the first certificate and the rest of the chain\n        X509Certificate[] restOfTheChain = new X509Certificate[chain.length - 1];\n        System.arraycopy(chain, 1, restOfTheChain, 0, chain.length - 1);\n        CertificateUtils.writeCertificateToPEM(chain[0], certificateChainFile, restOfTheChain);\n    }\n\n    public static X509Certificate loadCertificateFromPEM(String pemFilePath) throws IOException, CertificateException {\n        try (PemReader pemReader = new PemReader(new FileReader(pemFilePath))) {\n            PemObject pemObject = pemReader.readPemObject();\n            if (pemObject == null) {\n                throw new IOException(\"Invalid PEM file: No PEM content found.\");\n            }\n            byte[] content = pemObject.getContent();\n            CertificateFactory certificateFactory = CertificateFactory.getInstance(\"X.509\");\n            return (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(content));\n        }\n    }\n\n    public static String createAccount(AcmeClient acmeClient,\n            String letsEncryptPath,\n            boolean staging,\n            String contactEmail,\n            String acmeServerUrl,\n            String acmeStagingServerUrl) {\n        LOGGER.infof(\"\\uD83D\\uDD35 Creating %s ACME account\", (staging ? \"staging\" : \"production\"));\n\n        // Use defaults if not specified\n        String serverUrl = acmeServerUrl != null ? acmeServerUrl\n                : DEFAULT_ACME_URL;","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/tls-registry/cli/src/main/java/io/quarkus/tls/cli/letsencrypt/LetsEncryptHelpers.java#L51-L87","documentation":"loadCertificateFromPEM parses a PEM file using BouncyCastle's PemReader. If the file contains no recognizable PEM block (a line like '-----BEGIN ...-----'), readPemObject() returns null and the method throws this IOException. It signals the file is not a valid PEM-encoded certificate.","triggerScenarios":"Calling LetsEncryptHelpers.loadCertificateFromPEM with a path to a file whose content has no '-----BEGIN...'/'-----END...' delimiters — e.g. a DER-encoded cert, a private key in another format, an empty file, or an HTML error page saved as .pem.","commonSituations":"Downloading a certificate and accidentally saving the HTML error response; exporting a certificate as DER (.der/.crt binary) but naming it .pem; a truncated or corrupted download; pointing the tool at a PKCS#12/JKS keystore instead of a PEM file.","solutions":["Open the file and confirm it contains '-----BEGIN CERTIFICATE-----' and '-----END CERTIFICATE-----' lines","Convert a DER certificate to PEM: openssl x509 -inform der -in cert.der -out cert.pem","Re-export/re-download the certificate in PEM (base64) format from your CA","Verify the file path points to the actual certificate, not a keystore or private key file","Check the file is not empty or truncated (file size, cat the file)"],"exampleFix":"// before (file is DER)\nX509Certificate cert = LetsEncryptHelpers.loadCertificateFromPEM(\"cert.der\");\n// after: convert first\n// openssl x509 -inform der -in cert.der -out cert.pem\nX509Certificate cert = LetsEncryptHelpers.loadCertificateFromPEM(\"cert.pem\");","handlingStrategy":"validation","validationCode":"boolean isPem(String path) throws IOException {\n    String content = Files.readString(Paths.get(path));\n    return content.contains(\"-----BEGIN CERTIFICATE-----\") && content.contains(\"-----END CERTIFICATE-----\");\n}\nif (!isPem(pemFilePath)) throw new IllegalArgumentException(\"Not a PEM certificate: \" + pemFilePath);\nX509Certificate cert = LetsEncryptHelpers.loadCertificateFromPEM(pemFilePath);","typeGuard":"boolean looksLikePem(byte[] bytes) {\n    String head = new String(bytes, 0, Math.min(bytes.length, 64), StandardCharsets.US_ASCII).trim();\n    return head.startsWith(\"-----BEGIN \");\n}","tryCatchPattern":"try {\n    X509Certificate cert = LetsEncryptHelpers.loadCertificateFromPEM(path);\n} catch (IOException | CertificateException e) {\n    // e.getMessage() == \"Invalid PEM file: No PEM content found.\"\n    throw new IllegalArgumentException(\"File is not PEM-encoded: \" + path + \". Convert with: openssl x509 -inform der -in file -out file.pem\", e);\n}","preventionTips":["Always verify the file starts with '-----BEGIN' before parsing","Use 'openssl x509 -in file -text -noout' to sanity-check certificates before use","Never rename DER/keystore files to .pem without converting them","Validate downloaded files are actual certificates, not HTML error pages"],"tags":["pem","certificate","io","tls"],"backgroundTag":"invalid-pem-file","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}