spring-projects/spring-security · error · IllegalArgumentException
String is not PEM encoded data, nor a public key encoded for
Error message
String is not PEM encoded data, nor a public key encoded for ssh
What it means
RsaKeyHelper.parseKeyPair() first tries to interpret the input string as PEM data or an SSH public key; if both attempts fail (or the string matched nothing) it throws this IllegalArgumentException. It means the supplied string is neither PEM-encoded key material nor an ssh-rsa encoded public key.
Source
Thrown at crypto/src/main/java/org/springframework/security/crypto/encrypt/RsaKeyHelper.java:83
private static final byte[] PREFIX = new byte[] { 0, 0, 0, 7, 's', 's', 'h', '-', 'r', 's', 'a' };
private RsaKeyHelper() {
}
static KeyPair parseKeyPair(String pemData) {
Matcher m = PEM_DATA.matcher(pemData.replaceAll("\n *", "").trim());
if (!m.matches()) {
try {
RSAPublicKey publicValue = extractPublicKey(pemData);
if (publicValue != null) {
return new KeyPair(publicValue, null);
}
}
catch (Exception ex) {
// Ignore
}
throw new IllegalArgumentException("String is not PEM encoded data, nor a public key encoded for ssh");
}
String type = m.group(1);
final byte[] content = base64Decode(m.group(2));
PublicKey publicKey;
PrivateKey privateKey = null;
try {
KeyFactory fact = KeyFactory.getInstance("RSA");
switch (type) {
case "RSA PRIVATE KEY" -> {
ASN1Sequence seq = ASN1Sequence.getInstance(content);
if (seq.size() != 9) {
throw new IllegalArgumentException("Invalid RSA Private Key ASN1 sequence.");
}
org.bouncycastle.asn1.pkcs.RSAPrivateKey key = org.bouncycastle.asn1.pkcs.RSAPrivateKey
.getInstance(seq);View on GitHub (pinned to 96852e8860)
Solutions
- Ensure the string is proper PEM with header/footer, e.g. -----BEGIN RSA PRIVATE KEY----- ... -----END RSA PRIVATE KEY-----
- Convert OpenSSH-format keys to PEM: ssh-keygen -p -m PEM -f id_rsa
- Strip whitespace/BOM and re-save the key file as UTF-8/ASCII
- Confirm you are passing the key, not an X.509 certificate; extract the key from the cert if needed
Example fix
// before
KeyPair kp = RsaKeyHelper.parseKeyPair("MIICdgIBADANBg..."); // raw base64, no PEM
// after
KeyPair kp = RsaKeyHelper.parseKeyPair(
"-----BEGIN RSA PRIVATE KEY-----\nMIICdgIBADANBg...\n-----END RSA PRIVATE KEY-----"); Defensive patterns
Strategy: validation
Validate before calling
boolean isPem(String s) {
return s != null && s.contains("-----BEGIN") && s.contains("-----END");
}
if (!isPem(keyString)) throw new IllegalArgumentException("Key must be PEM encoded"); Type guard
static boolean isPemEncoded(String s) {
return s != null && s.trim().startsWith("-----BEGIN") && s.trim().contains("-----END");
} Try / catch
try { return RsaKeyHelper.parseKeyPair(pem); } catch (IllegalArgumentException ex) { throw new BadConfigurationException("Key material must be PEM or ssh-rsa encoded", ex); } Prevention
- Convert OpenSSH keys to PEM with ssh-keygen -m PEM
- Always copy keys including BEGIN/END header lines
- Read key files as UTF-8/ASCII text
- Validate the header type matches RSA before parsing
When it happens
Trigger: Passing a raw modulus/hex string, a base64 blob without PEM headers, an empty or whitespace-only string, or a wrongly formatted PEM (missing BEGIN/END lines) into parseKeyPair().
Common situations: Copying a key from a terminal losing the BEGIN/END header lines; pasting an OpenSSH-format key (ssh-ed25519 or new OpenSSH private key format) that the ssh-rsa regex does not match; reading the key file with wrong encoding (UTF-16); accidentally passing a certificate instead of a 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
- Invalid RSA Private Key ASN1 sequence.
- is not a supported format
- Cannot load keys from store:
- Only RSA is currently supported, but algorithm was
- Key data does not contain a public key
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/9b2df0156c59684a.
Report an issue: GitHub.