spring-projects/spring-security · error · IllegalArgumentException

secretKeyFactoryAlgorithm cannot be null

Error message

secretKeyFactoryAlgorithm cannot be null

What it means

Pbkdf2PasswordEncoder.setAlgorithm throws this IllegalArgumentException when handed a null SecretKeyFactoryAlgorithm. The encoder must know which PBKDF2 variant (SHA1/SHA256/SHA512) to request from the JCA SecretKeyFactory, so a null algorithm is invalid configuration. The constructor calls this setter, so passing null there triggers it too.

Source

Thrown at crypto/src/main/java/org/springframework/security/crypto/password/Pbkdf2PasswordEncoder.java:170

	 * @since 5.8
	 */
	public static Pbkdf2PasswordEncoder defaultsForSpringSecurity_v5_8() {
		return new Pbkdf2PasswordEncoder("", DEFAULT_SALT_LENGTH, DEFAULT_ITERATIONS, DEFAULT_ALGORITHM);
	}

	/**
	 * Sets the algorithm to use. See <a href=
	 * "https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SecretKeyFactory">SecretKeyFactory
	 * Algorithms</a>
	 * @param secretKeyFactoryAlgorithm the algorithm to use (i.e.
	 * {@code SecretKeyFactoryAlgorithm.PBKDF2WithHmacSHA1},
	 * {@code SecretKeyFactoryAlgorithm.PBKDF2WithHmacSHA256},
	 * {@code SecretKeyFactoryAlgorithm.PBKDF2WithHmacSHA512})
	 * @since 5.0
	 */
	public void setAlgorithm(SecretKeyFactoryAlgorithm secretKeyFactoryAlgorithm) {
		if (secretKeyFactoryAlgorithm == null) {
			throw new IllegalArgumentException("secretKeyFactoryAlgorithm cannot be null");
		}
		String algorithmName = secretKeyFactoryAlgorithm.name();
		try {
			SecretKeyFactory.getInstance(algorithmName);
			this.algorithm = algorithmName;
		}
		catch (NoSuchAlgorithmException ex) {
			throw new IllegalArgumentException("Invalid algorithm '" + algorithmName + "'.", ex);
		}
		if (this.overrideHashWidth) {
			this.hashWidth = SecretKeyFactoryAlgorithm.PBKDF2WithHmacSHA1.equals(secretKeyFactoryAlgorithm) ? 160
					: SecretKeyFactoryAlgorithm.PBKDF2WithHmacSHA256.equals(secretKeyFactoryAlgorithm) ? 256 : 512;
		}
	}

	/**
	 * Sets if the resulting hash should be encoded as Base64. The default is false which
	 * means it will be encoded in Hex.

View on GitHub (pinned to 96852e8860)

Solutions

  1. Pass an explicit algorithm: setAlgorithm(SecretKeyFactoryAlgorithm.PBKDF2WithHmacSHA256).
  2. Guard before calling: if (algo != null) encoder.setAlgorithm(algo); else use the encoder default.
  3. Give the configuration property a non-null default (e.g. PBKDF2WithHmacSHA256) in your settings loader.

Example fix

// before
encoder.setAlgorithm(config.getPbkdf2Algorithm()); // may be null
// after
SecretKeyFactoryAlgorithm algo = config.getPbkdf2Algorithm();
encoder.setAlgorithm(algo != null ? algo : SecretKeyFactoryAlgorithm.PBKDF2WithHmacSHA256);
Defensive patterns

Strategy: type-guard

Validate before calling

if (algo == null) algo = SecretKeyFactoryAlgorithm.PBKDF2WithHmacSHA256;
encoder.setAlgorithm(algo);

Type guard

SecretKeyFactoryAlgorithm safe = java.util.Optional.ofNullable(configured)
    .orElse(SecretKeyFactoryAlgorithm.PBKDF2WithHmacSHA256);

Try / catch

try {
    encoder.setAlgorithm(algo);
} catch (IllegalArgumentException e) {
    encoder.setAlgorithm(SecretKeyFactoryAlgorithm.PBKDF2WithHmacSHA1);
}

Prevention

When it happens

Trigger: Calling encoder.setAlgorithm(null), or constructing Pbkdf2PasswordEncoder with code that forwards a nullable algorithm variable resolved from configuration.

Common situations: Configuration mapping where the algorithm enum is missing and defaults to null; refactors replacing a default algorithm without updating all construction sites.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/2533ad5dcbbd9a92. Report an issue: GitHub.