spring-projects/spring-security · error · IllegalArgumentException

Unable to initialize due to invalid secret key

Error message

Unable to initialize due to invalid secret key

What it means

Thrown by CipherUtils.initCipher when cipher.init(mode, key, params) throws InvalidKeyException. The SecretKey supplied is not acceptable for the cipher: wrong algorithm type, wrong length, or otherwise unusable key material.

Solutions

  1. Ensure the key is an AES key of valid length (16, 24, or 32 bytes) — decode hex/base64 config values to raw bytes before building SecretKeySpec.
  2. On Java 8 before 8u161, install JCE Unlimited Strength policy files or upgrade to get AES-256 support.
  3. Use Spring Security's factory methods (new AesBytesEncryptor(password, salt)) so key derivation is done correctly.
  4. Log key length (secretKey.getEncoded().length) and algorithm at debug level to diagnose mismatches.

Example fix

// before
SecretKey key = new SecretKeySpec(passphrase.getBytes(), "AES"); // length not 16/24/32
// after
byte[] keyBytes = Hex.decode(hexKey); // must decode to exactly 16/24/32 bytes
SecretKey key = new SecretKeySpec(keyBytes, "AES");
Defensive patterns

Strategy: validation

Validate before calling

if (secretKey.getEncoded() == null ||
    !(secretKey.getEncoded().length == 16 || secretKey.getEncoded().length == 24 || secretKey.getEncoded().length == 32)) {
    throw new IllegalArgumentException("AES key must be 16/24/32 bytes, got " +
        (secretKey.getEncoded() == null ? "null" : secretKey.getEncoded().length));
}

Try / catch

try {
    CipherUtils.initCipher(cipher, Cipher.ENCRYPT_MODE, key, spec);
} catch (IllegalArgumentException ex) {
    throw new ConfigurationException("Key rejected by cipher (wrong type/length or JCE policy)", ex);
}

Prevention

When it happens

Trigger: Calling an AesBytesEncryptor built with a non-AES SecretKey or a key of the wrong length (not 128/192/256 bits); passing a password-derived key whose keyLength exceeds the JVM's policy limit; passing null or a DES key to an AES cipher.

Common situations: Constructing encryptors with hand-built SecretKeySpec of incorrect length; older Java 8 without unlimited-strength JCE policy when using AES-256; key material from config that was mis-decoded (e.g. hex string not decoded to raw bytes, yielding wrong key length).

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/8ae196afa1a6f81f. Report an issue: GitHub.

Appendix: source

Thrown at crypto/src/main/java/org/springframework/security/crypto/encrypt/CipherUtils.java:125

	static void initCipher(Cipher cipher, int mode, SecretKey secretKey, byte[] salt, int iterationCount) {
		initCipher(cipher, mode, secretKey, new PBEParameterSpec(salt, iterationCount));
	}

	/**
	 * 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) {

View on GitHub (pinned to 96852e8860)