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

  1. 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-----'
  2. Check you did not swap the key and certificate paths in the encryption options
  3. Ensure YAML multi-line strings preserve newlines (use proper block scalar '|' indentation or a filesystem path reference)
  4. Confirm the key file is a PEM text file, not a binary keystore (JKS/PKCS12); export a PEM key if needed
  5. 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

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


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/78ea2f0d1b311c81. Report an issue: GitHub.