spring-projects/spring-security · error · IllegalStateException
Unable to initialize due to invalid decryption parameter spe
Error message
Unable to initialize due to invalid decryption parameter spec
What it means
Thrown by CipherUtils.initCipher when cipher.init(mode, key, params) throws InvalidAlgorithmParameterException. The AlgorithmParameterSpec (typically the IV/GCM parameters) provided for decryption is invalid for the cipher: null when required, wrong class, or wrong length (e.g. a non-16-byte IV for AES-CBC).
Source
Thrown at crypto/src/main/java/org/springframework/security/crypto/encrypt/CipherUtils.java:128
/**
* Initializes the Cipher for use.
*/
static void initCipher(Cipher cipher, int mode, SecretKey secretKey,
@Nullable AlgorithmParameterSpec parameterSpec) {
try {
if (parameterSpec != null) {
cipher.init(mode, secretKey, parameterSpec);
}
else {
cipher.init(mode, secretKey);
}
}
catch (InvalidKeyException ex) {
throw new IllegalArgumentException("Unable to initialize due to invalid secret key", ex);
}
catch (InvalidAlgorithmParameterException ex) {
throw new IllegalStateException("Unable to initialize due to invalid decryption parameter spec", ex);
}
}
/**
* Invokes the Cipher to perform encryption or decryption (depending on the
* initialized mode).
*/
static byte[] doFinal(Cipher cipher, byte[] input) {
try {
return cipher.doFinal(input);
}
catch (IllegalBlockSizeException ex) {
throw new IllegalStateException("Unable to invoke Cipher due to illegal block size", ex);
}
catch (BadPaddingException ex) {
throw new IllegalStateException("Unable to invoke Cipher due to bad padding", ex);
}
}View on GitHub (pinned to 96852e8860)
Solutions
- Store and retrieve the full IV/nonce with the ciphertext and pass the exact bytes when constructing the spec.
- Use the correct spec class and lengths: IvParameterSpec with a 16-byte IV for AES-CBC; GCMParameterSpec(tagLenBits, nonce) for GCM.
- Verify the parameter spec survives your serialization (Base64 the IV rather than raw string round-trips).
- Check you're not passing null params to init when the mode requires them.
Example fix
// before byte[] iv = storedValue.getBytes(); // truncated/corrupted Cipher cipher = CipherUtils.initCipher(cipher, Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv)); // after byte[] iv = Base64.getDecoder().decode(storedIvBase64); // full 16 bytes as produced at encryption time Cipher cipher = CipherUtils.initCipher(cipher, Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
Defensive patterns
Strategy: validation
Validate before calling
if (iv == null || iv.length != 16) {
throw new IllegalArgumentException("CBC IV must be exactly 16 bytes, got " + (iv == null ? "null" : iv.length));
} Try / catch
try {
CipherUtils.initCipher(cipher, Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
} catch (IllegalStateException ex) {
throw new DataCorruptionException("Invalid IV for decryption — IV missing or altered", ex);
} Prevention
- Always persist the IV alongside ciphertext (Base64-encoded, fixed length).
- Store IVs in lossless columns (VARBINARY or Base64 TEXT), never padded CHAR fields.
- For GCM use GCMParameterSpec with the original nonce and tag length.
- Include IV round-trip in integration tests.
When it happens
Trigger: Decrypting with an IvParameterSpec built from an IV that was never stored or was corrupted; passing a null parameter spec to a mode that requires one; using a GCMParameterSpec with wrong tag length; reusing encryptor state such that the decrypt path receives an invalid spec.
Common situations: IV not persisted alongside ciphertext (schema change dropped the IV column); IV truncated during transport/encoding; migration between CBC and GCM where the parameter spec class changed; provider quirks on FIPS JVMs.
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
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/ca72f03baf9405e9.
Report an issue: GitHub.