apache/cassandra · error · GeneralSecurityException
Invalid private key format
Error message
Invalid private key format
What it means
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.
Source
Thrown at src/java/org/apache/cassandra/security/PEMReader.java:238
}
/**
* 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>.
*
* @param pemKey private key stored as PEM content
* @return base64 string contained within the defined encapsulation boundaries by the above RFC
* @throws GeneralSecurityException in case any issue encountered while parsing the key
*/
private static String extractBase64EncodedKey(String pemKey) throws GeneralSecurityException
{
Matcher matcher = KEY_PATTERN.matcher(pemKey);
if (matcher.find())
{
return matcher.group(1).replaceAll("\\s", "");
}
else
{
throw new GeneralSecurityException("Invalid private key format");
}
}
/**
* Parses the PEM formatted certificate/public-key based on the standard pattern specified by the
* <a href="https://datatracker.ietf.org/doc/html/rfc7468#section-13">RFC 7468</a>.
*
* @param pemCerts certificate/public-key stored as PEM content
* @return list of base64 encoded certificates within the defined encapsulation boundaries by the above RFC
* @throws GeneralSecurityException in case any issue encountered parsing the certificate
*/
private static List<String> extractBase64EncodedCerts(String pemCerts) throws GeneralSecurityException
{
List<String> certificateList = new ArrayList<>();
Matcher matcher = CERT_PATTERN.matcher(pemCerts);
if (!matcher.find())
{
throw new GeneralSecurityException("Invalid certificate format");View on GitHub (pinned to 88fd0f6a0e)
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
Example fix
# before: binary keystore referenced as PEM key openssl pkcs12 -in keystore.p12 # not PEM # after: export the private key as PEM openssl pkcs12 -in keystore.p12 -nodes -nocerts -out cassandra.key
Defensive patterns
Strategy: validation
Validate before calling
// Check PEM key markers before calling the API
static boolean looksLikePemPrivateKey(String pem) {
return pem != null && pem.matches("(?s).*-----+\\s*BEGIN\\s+.*PRIVATE\\s+KEY[^-]*-+.*")
&& pem.matches("(?s).*-----+\\s*END\\s+.*PRIVATE\\s+KEY[^-]*-+.*");
} Try / catch
try {
PrivateKey key = PEMReader.extractPrivateKey(pemKey);
} catch (GeneralSecurityException e) {
if (e.getMessage().contains("Invalid private key format")) {
logger.error("Configured key does not contain a BEGIN/END PRIVATE KEY PEM block - check key vs cert paths in cassandra.yaml");
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- The given private key could not be parsed with any of the su
- Invalid certificate format
- Failed to decode given base64 input. msg=
- Access denied
- Access Denied
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/78ea2f0d1b311c81.
Report an issue: GitHub.