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

  1. Ensure the string is proper PEM with header/footer, e.g. -----BEGIN RSA PRIVATE KEY----- ... -----END RSA PRIVATE KEY-----
  2. Convert OpenSSH-format keys to PEM: ssh-keygen -p -m PEM -f id_rsa
  3. Strip whitespace/BOM and re-save the key file as UTF-8/ASCII
  4. 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

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


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/9b2df0156c59684a. Report an issue: GitHub.