spring-projects/spring-security · error · IllegalArgumentException

is not a supported format

Error message

 is not a supported format

What it means

parseKeyPair() switches on the PEM header type; any type other than the supported ones (RSA PRIVATE KEY, PUBLIC KEY, etc.) falls into the default branch and throws this IllegalArgumentException with the unsupported type name prepended. It means the key file declares a PEM block type this helper cannot parse.

Source

Thrown at crypto/src/main/java/org/springframework/security/crypto/encrypt/RsaKeyHelper.java:120

					RSAPublicKeySpec pubSpec = new RSAPublicKeySpec(key.getModulus(), key.getPublicExponent());
					RSAPrivateCrtKeySpec privSpec = new RSAPrivateCrtKeySpec(key.getModulus(), key.getPublicExponent(),
							key.getPrivateExponent(), key.getPrime1(), key.getPrime2(), key.getExponent1(),
							key.getExponent2(), key.getCoefficient());
					publicKey = fact.generatePublic(pubSpec);
					privateKey = fact.generatePrivate(privSpec);
				}
				case "PUBLIC KEY" -> {
					KeySpec keySpec = new X509EncodedKeySpec(content);
					publicKey = fact.generatePublic(keySpec);
				}
				case "RSA PUBLIC KEY" -> {
					ASN1Sequence seq = ASN1Sequence.getInstance(content);
					org.bouncycastle.asn1.pkcs.RSAPublicKey key = org.bouncycastle.asn1.pkcs.RSAPublicKey
						.getInstance(seq);
					RSAPublicKeySpec pubSpec = new RSAPublicKeySpec(key.getModulus(), key.getPublicExponent());
					publicKey = fact.generatePublic(pubSpec);
				}
				default -> throw new IllegalArgumentException(type + " is not a supported format");
			}

			return new KeyPair(publicKey, privateKey);
		}
		catch (InvalidKeySpecException ex) {
			throw new RuntimeException(ex);
		}
		catch (NoSuchAlgorithmException ex) {
			throw new IllegalStateException(ex);
		}
	}

	private static byte[] base64Decode(String string) {
		try {
			ByteBuffer bytes = UTF8.newEncoder().encode(CharBuffer.wrap(string));
			byte[] bytesCopy = new byte[bytes.limit()];
			System.arraycopy(bytes.array(), 0, bytesCopy, 0, bytes.limit());
			return Base64.getDecoder().decode(bytesCopy);

View on GitHub (pinned to 96852e8860)

Solutions

  1. Convert the key to an unencrypted RSA PEM: openssl rsa -in key.pem -out unencrypted.pem
  2. Regenerate with PEM RSA format: ssh-keygen -m PEM -t rsa -b 2048
  3. Use an RSA key rather than EC/DSA, or a different helper supporting that type
  4. Extract the key from the certificate if a cert was passed by mistake

Example fix

// before
-----BEGIN OPENSSH PRIVATE KEY----- ... // unsupported
// after
ssh-keygen -p -m PEM -f id_rsa   // yields -----BEGIN RSA PRIVATE KEY-----
Defensive patterns

Strategy: validation

Validate before calling

java.util.regex.Matcher m = java.util.regex.Pattern
    .compile("-----BEGIN (RSA PRIVATE KEY|PUBLIC KEY|RSA PUBLIC KEY)-----")
    .matcher(pem);
if (!m.find()) throw new IllegalArgumentException("Unsupported PEM type: use RSA PRIVATE KEY or PUBLIC KEY");

Type guard

static boolean supportedPemType(String pem) {
    return pem != null && pem.matches("(?s).*-----BEGIN (RSA PRIVATE KEY|PUBLIC KEY|RSA PUBLIC KEY)-----.*");
}

Try / catch

try { return RsaKeyHelper.parseKeyPair(pem); } catch (IllegalArgumentException ex) { throw new UnsupportedKeyFormatException(pem == null ? null : pem.substring(0, Math.min(40, pem.length())), ex); }

Prevention

When it happens

Trigger: Input PEM begins with e.g. -----BEGIN ENCRYPTED PRIVATE KEY-----, -----BEGIN EC PRIVATE KEY-----, -----BEGIN CERTIFICATE-----, or a new OpenSSH 'OPENSSH PRIVATE KEY' header, which is not among the handled switch cases.

Common situations: Using elliptic-curve keys instead of RSA; using password-protected (encrypted) PEMs; OpenSSH's default private key format (ssh-keygen without -m PEM); passing a certificate chain file instead of a key.

Related errors


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