{"record":{"id":"df04eb79c5ad8309","repo":"apache/hadoop","slug":"certificateexception-pem-may-be-corrupt","errorCode":null,"errorMessage":"CertificateException - PEM may be corrupt","messagePattern":"CertificateException - PEM may be corrupt","errorType":"exception","errorClass":"ServletException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/CertificateUtil.java","lineNumber":60,"sourceCode":"  public static RSAPublicKey parseRSAPublicKey(String pem) throws ServletException {\n    String fullPem = PEM_HEADER + pem + PEM_FOOTER;\n    PublicKey key = null;\n    try {\n      CertificateFactory fact = CertificateFactory.getInstance(\"X.509\");\n      ByteArrayInputStream is = new ByteArrayInputStream(\n          fullPem.getBytes(StandardCharsets.UTF_8));\n\n      X509Certificate cer = (X509Certificate) fact.generateCertificate(is);\n      key = cer.getPublicKey();\n    } catch (CertificateException ce) {\n      String message = null;\n      if (pem.startsWith(PEM_HEADER)) {\n        message = \"CertificateException - be sure not to include PEM header \"\n            + \"and footer in the PEM configuration element.\";\n      } else {\n        message = \"CertificateException - PEM may be corrupt\";\n      }\n      throw new ServletException(message, ce);\n    }\n    return (RSAPublicKey) key;\n  }\n}\n","sourceCodeStart":42,"sourceCodeEnd":65,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/CertificateUtil.java#L42-L65","documentation":"The other failure branch of CertificateUtil.parseRSAPublicKey(): the input did not start with the PEM header, so the code wrapped it with header/footer itself, yet the JDK CertificateFactory still threw CertificateException. This means the base64 body itself is not parseable as an X.509 certificate.","triggerScenarios":"Passing a bare public key PEM ('-----BEGIN PUBLIC KEY-----' body from 'openssl rsa -pubout') instead of a certificate; truncated base64 body; body containing whitespace, dashes, or other non-base64 characters; a DER-encoded (binary) certificate pasted into config.","commonSituations":"Users extracting only the key pair with openssl and assuming the public key equals the certificate; copy/paste losing characters; terminal line-wrap injecting breaks into long base64 lines.","solutions":["Verify the body decodes standalone: wrap it with BEGIN/END CERTIFICATE lines and run 'openssl x509 -in wrapped.pem -noout'","If you exported a bare public key, export the certificate instead ('openssl x509 -in cert.pem') and use its base64 body","Remove \\r, spaces and stray characters, and ensure the base64 text is complete"],"exampleFix":"# before: body of a bare RSA public key (not a certificate)\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...\n\n# after: base64 body of the X.509 certificate containing that key\nopenssl x509 -in server-cert.pem | sed -n '2,$p' | head -n -1","handlingStrategy":"validation","validationCode":"boolean looksLikeCertBody(String pem) {\n  String body = pem.replaceAll(\"\\\\s\", \"\");\n  if (!body.matches(\"[A-Za-z0-9+/]+=*\")) return false;\n  try { java.util.Base64.getDecoder().decode(body); return true; }\n  catch (IllegalArgumentException e) { return false; }\n}","typeGuard":null,"tryCatchPattern":"try { RSAPublicKey k = CertificateUtil.parseRSAPublicKey(pem); } catch (ServletException e) { /* fail fast; check cause chain for the CertificateException */ }","preventionTips":["Verify the blob is a certificate, not a bare public key: openssl x509 must accept it","Prefer automating extraction: openssl x509 -in cert.pem | grep -v CERTIFICATE","Avoid manual copy/paste of long base64 through terminals that wrap lines"],"tags":["hadoop-auth","ssl-certificate","pem","configuration"],"backgroundTag":"invalid-pem-certificate","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}