spring-projects/spring-security · error · IllegalArgumentException
Key data does not contain a public key
Error message
Key data does not contain a public key
What it means
parsePublicKey parses the supplied key material into a KeyPair; if the resulting pair has no public component the method cannot return the RSAPublicKey it promises, so it throws this IllegalArgumentException.
Source
Thrown at crypto/src/main/java/org/springframework/security/crypto/encrypt/RsaKeyHelper.java:203
// "ssh-rsa" at the start
return parseSSHPublicKey(key);
}
return null;
}
static RSAPublicKey parsePublicKey(String key) {
RSAPublicKey publicKey = extractPublicKey(key);
if (publicKey != null) {
return publicKey;
}
KeyPair kp = parseKeyPair(key);
if (kp.getPublic() == null) {
throw new IllegalArgumentException("Key data does not contain a public key");
}
return (RSAPublicKey) kp.getPublic();
}
static String encodePublicKey(RSAPublicKey key, String id) {
StringWriter output = new StringWriter();
output.append("ssh-rsa ");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
stream.write(PREFIX);
writeBigInteger(stream, key.getPublicExponent());
writeBigInteger(stream, key.getModulus());
}
catch (IOException ex) {
throw new IllegalStateException("Cannot encode key", ex);
}View on GitHub (pinned to 96852e8860)
Solutions
- Supply the public key file (.pub) or a key string that includes public key data.
- If only a private key is available, derive the public key with openssl: 'openssl rsa -in id_rsa -pubout'.
- Verify the key parses with 'ssh-keygen -y -f keyfile' to confirm it contains public material.
- Check the key format matches what parseKeyPair supports (PEM/SSH RSA).
Example fix
// before RSAPublicKey pk = helper.parsePublicKey(privateKeyPem); // after RSAPublicKey pk = helper.parsePublicKey(publicKeyPem); // or ssh -style 'ssh-rsa AAAA...' string
Defensive patterns
Strategy: validation
Validate before calling
boolean containsPublicKey(String keyData) {
return keyData != null && (keyData.contains("ssh-rsa ") || keyData.contains("BEGIN PUBLIC KEY") || keyData.contains("BEGIN RSA PUBLIC KEY"));
} Try / catch
try {
RSAPublicKey pk = helper.parsePublicKey(keyData);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("does not contain a public key")) {
throw new ConfigException("Key file holds a private key; supply the .pub file or run: openssl rsa -in key -pubout");
}
throw e;
} Prevention
- Configure the .pub path, not the private key path.
- Derive a public key from a private one with 'openssl rsa -pubout' when only the private exists.
- Fail fast at startup by parsing the key once and caching the RSAPublicKey.
- Sanity-check with 'ssh-keygen -y -f keyfile' during deployment scripts.
When it happens
Trigger: Passing key data to parsePublicKey that contains only a private key (e.g. an unencrypted PKCS#8/OpenSSL private key file with no accompanying certificate), or corrupted data that parseKeyPair silently parsed into a public-less pair.
Common situations: Pointing configuration at a private key file (id_rsa) instead of the public key file (id_rsa.pub), or pasting the contents of a server's host key into a place expecting the public key.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Cannot load keys from store:
- Only RSA is currently supported, but algorithm was
- Cannot encode key
- Encryptor is not configured for decryption
- Cannot decrypt
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/51c46085ad232b4e.
Report an issue: GitHub.