{"record":{"id":"51c46085ad232b4e","repo":"spring-projects/spring-security","slug":"key-data-does-not-contain-a-public-key","errorCode":null,"errorMessage":"Key data does not contain a public key","messagePattern":"Key data does not contain a public key","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"crypto/src/main/java/org/springframework/security/crypto/encrypt/RsaKeyHelper.java","lineNumber":203,"sourceCode":"\t\t\t// \"ssh-rsa\" at the start\n\t\t\treturn parseSSHPublicKey(key);\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tstatic RSAPublicKey parsePublicKey(String key) {\n\n\t\tRSAPublicKey publicKey = extractPublicKey(key);\n\n\t\tif (publicKey != null) {\n\t\t\treturn publicKey;\n\t\t}\n\n\t\tKeyPair kp = parseKeyPair(key);\n\n\t\tif (kp.getPublic() == null) {\n\t\t\tthrow new IllegalArgumentException(\"Key data does not contain a public key\");\n\t\t}\n\n\t\treturn (RSAPublicKey) kp.getPublic();\n\n\t}\n\n\tstatic String encodePublicKey(RSAPublicKey key, String id) {\n\t\tStringWriter output = new StringWriter();\n\t\toutput.append(\"ssh-rsa \");\n\t\tByteArrayOutputStream stream = new ByteArrayOutputStream();\n\t\ttry {\n\t\t\tstream.write(PREFIX);\n\t\t\twriteBigInteger(stream, key.getPublicExponent());\n\t\t\twriteBigInteger(stream, key.getModulus());\n\t\t}\n\t\tcatch (IOException ex) {\n\t\t\tthrow new IllegalStateException(\"Cannot encode key\", ex);\n\t\t}","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/crypto/src/main/java/org/springframework/security/crypto/encrypt/RsaKeyHelper.java#L185-L221","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\nRSAPublicKey pk = helper.parsePublicKey(privateKeyPem);\n// after\nRSAPublicKey pk = helper.parsePublicKey(publicKeyPem); // or ssh -style 'ssh-rsa AAAA...' string","handlingStrategy":"validation","validationCode":"boolean containsPublicKey(String keyData) {\n    return keyData != null && (keyData.contains(\"ssh-rsa \") || keyData.contains(\"BEGIN PUBLIC KEY\") || keyData.contains(\"BEGIN RSA PUBLIC KEY\"));\n}","typeGuard":null,"tryCatchPattern":"try {\n    RSAPublicKey pk = helper.parsePublicKey(keyData);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"does not contain a public key\")) {\n        throw new ConfigException(\"Key file holds a private key; supply the .pub file or run: openssl rsa -in key -pubout\");\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["rsa","public-key","crypto","key-format"],"backgroundTag":"invalid-argument-value","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}