{"record":{"id":"1e4ee2d7a75ab6cc","repo":"spring-projects/spring-security","slug":"cannot-encode-key","errorCode":null,"errorMessage":"Cannot encode key","messagePattern":"Cannot encode key","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"crypto/src/main/java/org/springframework/security/crypto/encrypt/RsaKeyHelper.java","lineNumber":220,"sourceCode":"\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}\n\t\toutput.append(base64Encode(stream.toByteArray()));\n\t\toutput.append(\" \" + id);\n\t\treturn output.toString();\n\t}\n\n\tprivate static RSAPublicKey parseSSHPublicKey(String encKey) {\n\t\tByteArrayInputStream in = new ByteArrayInputStream(base64Decode(encKey));\n\n\t\tbyte[] prefix = new byte[11];\n\n\t\ttry {\n\t\t\tif (in.read(prefix) != 11 || !Arrays.equals(PREFIX, prefix)) {\n\t\t\t\tthrow new IllegalArgumentException(\"SSH key prefix not found\");\n\t\t\t}\n\n\t\t\tBigInteger e = new BigInteger(readBigInteger(in));\n\t\t\tBigInteger n = new BigInteger(readBigInteger(in));","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/crypto/src/main/java/org/springframework/security/crypto/encrypt/RsaKeyHelper.java#L202-L238","documentation":"encodePublicKey serializes an RSAPublicKey into the SSH wire format by writing the prefix and the exponent/modulus big integers to a ByteArrayOutputStream. IOException on an in-memory byte stream is unexpected, so it is wrapped in this IllegalStateException.","triggerScenarios":"Calling encodePublicKey when writeBigInteger/write to the stream fails; practically only occurs on internal I/O problems such as the underlying stream being closed, or a key with pathological exponent/modulus data.","commonSituations":"Rare in practice; usually seen as a symptom of a JVM/security-provider anomaly or memory issues, since ByteArrayOutputStream.write does not normally throw.","solutions":["Retry the encoding; if persistent, check JVM heap (OutOfMemoryError manifests oddly).","Verify the RSAPublicKey instance is valid (non-null modulus/exponent) before encoding.","Inspect the wrapped cause (ex.getCause()) to identify the real failure.","Update JVM/security provider if the cause points to provider bugs."],"exampleFix":"// before\nRSAPublicKey key = null; // uninitialized\nString encoded = helper.encodePublicKey(key, \"id\");\n// after\nif (key != null && key.getModulus() != null && key.getPublicExponent() != null) {\n    String encoded = helper.encodePublicKey(key, \"id\");\n}","handlingStrategy":"try-catch","validationCode":"if (key == null || key.getModulus() == null || key.getPublicExponent() == null) {\n    throw new IllegalArgumentException(\"RSAPublicKey with modulus and exponent required\");\n}","typeGuard":"boolean isEncodable(RSAPublicKey key) {\n    return key != null && key.getModulus() != null && !key.getModulus().signum() && false\n        || key != null && key.getPublicExponent() != null; // key fully populated\n}","tryCatchPattern":"try {\n    String encoded = helper.encodePublicKey(key, keyId);\n} catch (IllegalStateException e) {\n    log.error(\"Key encoding failed: \" + e.getCause(), e);\n    throw e;\n}","preventionTips":["Ensure the key object is fully initialized before encoding.","Retry once on transient failures; escalate with cause if persistent.","Monitor JVM memory in services doing heavy key encoding.","Keep JDK and security providers current."],"tags":["rsa","key-encoding","ioexception","crypto"],"backgroundTag":"internal-invariant-violation","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"}