spring-projects/spring-security · error · IllegalStateException
Cannot encrypt
Error message
Cannot encrypt
What it means
RsaSecretEncryptor's static encrypt(byte[], PublicKey, RsaAlgorithm, String salt, boolean gcm) wraps any checked Exception (notably IOException from writeInt's ByteArrayOutputStream writes) into IllegalStateException("Cannot encrypt") with the cause attached. It signals failure while building the hybrid envelope (random AES key + RSA-encrypted key + payload).
Source
Thrown at crypto/src/main/java/org/springframework/security/crypto/encrypt/RsaSecretEncryptor.java:197
private static byte[] encrypt(byte[] text, PublicKey key, RsaAlgorithm alg, String salt, boolean gcm) {
byte[] random = KeyGenerators.secureRandom(16).generateKey();
BytesEncryptor aes = gcm ? Encryptors.stronger(new String(Hex.encode(random)), salt)
: Encryptors.standard(new String(Hex.encode(random)), salt);
try {
final Cipher cipher = Cipher.getInstance(alg.getJceName());
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] secret = cipher.doFinal(random);
ByteArrayOutputStream result = new ByteArrayOutputStream(text.length + 20);
writeInt(result, secret.length);
result.write(secret);
result.write(aes.encrypt(text));
return result.toByteArray();
}
catch (RuntimeException ex) {
throw ex;
}
catch (Exception ex) {
throw new IllegalStateException("Cannot encrypt", ex);
}
}
private static void writeInt(ByteArrayOutputStream result, int length) throws IOException {
byte[] data = new byte[2];
data[0] = (byte) ((length >> 8) & 0xFF);
data[1] = (byte) (length & 0xFF);
result.write(data);
}
private static int readInt(ByteArrayInputStream result) throws IOException {
byte[] b = new byte[2];
result.read(b);
return ((b[0] & 0xFF) << 8) | (b[1] & 0xFF);
}
private static byte[] decrypt(byte[] text, @Nullable PrivateKey key, RsaAlgorithm alg, String salt, boolean gcm) {
ByteArrayInputStream input = new ByteArrayInputStream(text);View on GitHub (pinned to 96852e8860)
Solutions
- Inspect the wrapped cause via ex.getCause() to find the underlying exception.
- Ensure the JVM has adequate heap if encrypting very large payloads — consider streaming or splitting large data.
- Retry encryption; the random key generation makes failures essentially transient only if caused by resource pressure.
- Update/verify the Spring Security crypto version if the cause points to a library bug.
Example fix
// before
byte[] out = secretEncryptor.encrypt(hugePayload); // may wrap OOM/IO failure
// after
if (hugePayload.length > MAX_ENVELOPE_SIZE) {
throw new IllegalArgumentException("payload too large for RSA envelope encryption");
}
byte[] out = secretEncryptor.encrypt(hugePayload); Defensive patterns
Strategy: try-catch
Validate before calling
if (payload == null || payload.length == 0) throw new IllegalArgumentException("payload required");
if (publicKey == null) throw new IllegalArgumentException("public key required for encryption"); Type guard
boolean encryptable(RsaSecretEncryptor enc, byte[] payload) { return enc != null && payload != null && payload.length > 0; } Try / catch
try {
return encryptor.encrypt(payload);
} catch (IllegalStateException ex) {
logger.error("Encryption failed: " + ex.getCause(), ex);
throw new SecurityException("Encryption failed", ex);
} Prevention
- Always inspect ex.getCause() — the IllegalStateException is only a wrapper.
- Keep payloads within reasonable size limits; hybrid RSA envelopes are not for bulk data.
- Ensure ByteArrayOutputStream/I/O resources are not constrained (sufficient heap).
- Round-trip test encrypt/decrypt with the same algorithm, salt, and gcm settings.
When it happens
Trigger: IOException while writing the envelope structure into the internal ByteArrayOutputStream during encryption; any checked exception thrown inside the static encrypt path.
Common situations: Extremely large output causing memory pressure/OutOfMemoryError surfacing near this path; subtle I/O failure in the envelope writer; debugging unexpected encryption failures where the real cause is in ex.getCause().
Related errors
- Private key must be provided for decryption
- Cannot encrypt
- Cannot decrypt
- Encryptor is not configured for decryption
- Cannot apply {configurer} to already built object
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/ef71376d284ea4cb.
Report an issue: GitHub.