spring-projects/spring-security · error · IllegalArgumentException

Cpu cost parameter must be > 1 and < 65536.

Error message

Cpu cost parameter must be > 1 and < 65536.

What it means

SCryptPasswordEncoder's 5-arg constructor validates the scrypt work-factor parameters before hashing. The cpuCost (N) must be > 1, and when memoryCost (r) == 1 it is additionally capped at 65536 because the scrypt block-size/runtime trade-off becomes invalid. The library throws IllegalArgumentException immediately rather than producing broken hashes.

Source

Thrown at crypto/src/main/java/org/springframework/security/crypto/scrypt/SCryptPasswordEncoder.java:102

	 * Constructs a SCrypt password encoder with the provided parameters.
	 * @param cpuCost cpu cost of the algorithm (as defined in scrypt this is N). must be
	 * power of 2 greater than 1. Default is currently 65,536 or 2^16)
	 * @param memoryCost memory cost of the algorithm (as defined in scrypt this is r)
	 * Default is currently 8.
	 * @param parallelization the parallelization of the algorithm (as defined in scrypt
	 * this is p) Default is currently 1. Note that the implementation does not currently
	 * take advantage of parallelization.
	 * @param keyLength key length for the algorithm (as defined in scrypt this is dkLen).
	 * The default is currently 32.
	 * @param saltLength salt length (as defined in scrypt this is the length of S). The
	 * default is currently 16.
	 */
	public SCryptPasswordEncoder(int cpuCost, int memoryCost, int parallelization, int keyLength, int saltLength) {
		if (cpuCost <= 1) {
			throw new IllegalArgumentException("Cpu cost parameter must be > 1.");
		}
		if (memoryCost == 1 && cpuCost > 65536) {
			throw new IllegalArgumentException("Cpu cost parameter must be > 1 and < 65536.");
		}
		if (memoryCost < 1) {
			throw new IllegalArgumentException("Memory cost must be >= 1.");
		}
		int maxParallel = Integer.MAX_VALUE / (128 * memoryCost * 8);
		if (parallelization < 1 || parallelization > maxParallel) {
			throw new IllegalArgumentException("Parallelisation parameter p must be >= 1 and <= " + maxParallel
					+ " (based on block size r of " + memoryCost + ")");
		}
		if (keyLength < 1 || keyLength > Integer.MAX_VALUE) {
			throw new IllegalArgumentException("Key length must be >= 1 and <= " + Integer.MAX_VALUE);
		}
		if (saltLength < 1 || saltLength > Integer.MAX_VALUE) {
			throw new IllegalArgumentException("Salt length must be >= 1 and <= " + Integer.MAX_VALUE);
		}
		this.cpuCost = cpuCost;
		this.memoryCost = memoryCost;
		this.parallelization = parallelization;

View on GitHub (pinned to 96852e8860)

Solutions

  1. Pass cpuCost as the raw N value (e.g. 16384 for 2^14), not the exponent.
  2. Ensure cpuCost >= 2; use the library default by calling the no-arg SCryptPasswordEncoder().
  3. If cpuCost must exceed 65536, raise memoryCost above 1 so the cap does not apply, or reduce N.

Example fix

// before
new SCryptPasswordEncoder(1, 1, 1, 32, 64);
// after
new SCryptPasswordEncoder(16384, 8, 1, 32, 64);
Defensive patterns

Strategy: validation

Validate before calling

if (cpuCost <= 1 || (memoryCost == 1 && cpuCost > 65536)) {
    throw new IllegalArgumentException("cpuCost must be > 1 (and <= 65536 when memoryCost == 1): " + cpuCost);
}
new SCryptPasswordEncoder(cpuCost, memoryCost, parallelization, keyLength, saltLength);

Try / catch

try {
    encoder = new SCryptPasswordEncoder(cpuCost, memoryCost, p, keyLen, saltLen);
} catch (IllegalArgumentException e) {
    encoder = new SCryptPasswordEncoder(); // fall back to defaults
}

Prevention

When it happens

Trigger: Calling `new SCryptPasswordEncoder(cpuCost, memoryCost, parallelization, keyLength, saltLength)` with cpuCost <= 1, or with memoryCost == 1 and cpuCost > 65536.

Common situations: Copy-pasting scrypt parameters from tuning articles where N is written as 0 or 1; computing N dynamically (e.g. 2^x) with a negative exponent; misreading the default constructor (N=16384) and passing the exponent itself as cpuCost.

Related errors


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