{"record":{"id":"78ea2f0d1b311c81","repo":"apache/cassandra","slug":"invalid-private-key-format","errorCode":null,"errorMessage":"Invalid private key format","messagePattern":"Invalid private key format","errorType":"exception","errorClass":"GeneralSecurityException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/security/PEMReader.java","lineNumber":238,"sourceCode":"    }\n\n    /**\n     * Parses the PEM formatted private key based on the standard pattern specified by the <a href=\"https://datatracker.ietf.org/doc/html/rfc7468#section-11\">RFC 7468</a>.\n     *\n     * @param pemKey private key stored as PEM content\n     * @return base64 string contained within the defined encapsulation boundaries by the above RFC\n     * @throws GeneralSecurityException in case any issue encountered while parsing the key\n     */\n    private static String extractBase64EncodedKey(String pemKey) throws GeneralSecurityException\n    {\n        Matcher matcher = KEY_PATTERN.matcher(pemKey);\n        if (matcher.find())\n        {\n            return matcher.group(1).replaceAll(\"\\\\s\", \"\");\n        }\n        else\n        {\n            throw new GeneralSecurityException(\"Invalid private key format\");\n        }\n    }\n\n    /**\n     * Parses the PEM formatted certificate/public-key based on the standard pattern specified by the\n     * <a href=\"https://datatracker.ietf.org/doc/html/rfc7468#section-13\">RFC 7468</a>.\n     *\n     * @param pemCerts certificate/public-key stored as PEM content\n     * @return list of base64 encoded certificates within the defined encapsulation boundaries by the above RFC\n     * @throws GeneralSecurityException in case any issue encountered parsing the certificate\n     */\n    private static List<String> extractBase64EncodedCerts(String pemCerts) throws GeneralSecurityException\n    {\n        List<String> certificateList = new ArrayList<>();\n        Matcher matcher = CERT_PATTERN.matcher(pemCerts);\n        if (!matcher.find())\n        {\n            throw new GeneralSecurityException(\"Invalid certificate format\");","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/security/PEMReader.java#L220-L256","documentation":"extractBase64EncodedKey applies the KEY_PATTERN regex (BEGIN/END ... PRIVATE KEY encapsulation boundaries per RFC 7468) to the supplied PEM string. If no match is found, meaning the string does not contain a recognizable PEM private key block, this GeneralSecurityException is thrown. Note the pattern accepts any 'PRIVATE KEY' label (including 'ENCRYPTED PRIVATE KEY' and 'RSA PRIVATE KEY') but the content must still be parseable downstream.","triggerScenarios":"Calling PEMReader.extractPrivateKey(...) (directly or via PEMBasedSslContextFactory loading the key from cassandra.yaml) when the key string is empty, contains a PUBLIC CERTIFICATE instead of a private key, uses nonstandard PEM headers (e.g. missing dashes, 'BEGIN PRIVATE-KEY'), or has whitespace/encoding issues that break the regex match.","commonSituations":"Swapping the key and certificate file paths in cassandra.yaml; YAML multi-line string folding destroying newlines or the BEGIN/END markers; pointing at a PKCS#12/JKS binary keystore file instead of a PEM file; config templating rendering an empty or placeholder value for the key.","solutions":["Verify the configured key value is actually a PEM private key file — first line should be '-----BEGIN ... PRIVATE KEY-----' and last line '-----END ... PRIVATE KEY-----'","Check you did not swap the key and certificate paths in the encryption options","Ensure YAML multi-line strings preserve newlines (use proper block scalar '|' indentation or a filesystem path reference)","Confirm the key file is a PEM text file, not a binary keystore (JKS/PKCS12); export a PEM key if needed","If using a template/config system, confirm the key placeholder was populated with the actual PEM content"],"exampleFix":"# before: binary keystore referenced as PEM key\nopenssl pkcs12 -in keystore.p12   # not PEM\n# after: export the private key as PEM\nopenssl pkcs12 -in keystore.p12 -nodes -nocerts -out cassandra.key","handlingStrategy":"validation","validationCode":"// Check PEM key markers before calling the API\nstatic boolean looksLikePemPrivateKey(String pem) {\n    return pem != null && pem.matches(\"(?s).*-----+\\\\s*BEGIN\\\\s+.*PRIVATE\\\\s+KEY[^-]*-+.*\")\n                      && pem.matches(\"(?s).*-----+\\\\s*END\\\\s+.*PRIVATE\\\\s+KEY[^-]*-+.*\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    PrivateKey key = PEMReader.extractPrivateKey(pemKey);\n} catch (GeneralSecurityException e) {\n    if (e.getMessage().contains(\"Invalid private key format\")) {\n        logger.error(\"Configured key does not contain a BEGIN/END PRIVATE KEY PEM block - check key vs cert paths in cassandra.yaml\");\n    }\n    throw e;\n}","preventionTips":["Confirm key and certificate_chain entries in cassandra.yaml are not swapped","Reference the key by filesystem path or as a properly indented YAML block scalar so newlines survive","Verify the file is a PEM text file ('head -1 key.pem' shows BEGIN ... PRIVATE KEY), not JKS/PKCS12 binary","After config templating, diff the rendered key against the source PEM to confirm markers survived"],"tags":["security","pem","private-key","regex-parse"],"backgroundTag":"invalid-argument-format","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}