spring-projects/spring-security · error · IllegalArgumentException

Parallelisation parameter p must be >= 1 and <= {maxParallel

Error message

Parallelisation parameter p must be >= 1 and <= {maxParallel} (based on block size r of {memoryCost})

What it means

scrypt's parallelization factor p must be >= 1 and bounded above by maxParallel = Integer.MAX_VALUE / (128 * r * 8), derived from the scrypt block size. The constructor computes this bound and throws IllegalArgumentException when p is outside it, preventing integer overflow and invalid scrypt invocations.

Source

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

	 * 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;
		this.keyLength = keyLength;
		this.saltGenerator = KeyGenerators.secureRandom(saltLength);
	}

	/**
	 * Constructs a SCrypt password encoder with cpu cost of 16,384, memory cost of 8,
	 * parallelization of 1, a key length of 32 and a salt length of 64 bytes.

View on GitHub (pinned to 96852e8860)

Solutions

  1. Set parallelization >= 1 (default is 1 in the library).
  2. Clamp p to the max stated in the exception message for the chosen memoryCost.
  3. If a higher p is needed, decrease memoryCost (r) to raise the allowed maximum.

Example fix

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

Strategy: validation

Validate before calling

int maxParallel = Integer.MAX_VALUE / (128 * memoryCost * 8);
if (p < 1 || p > maxParallel) {
    p = Math.max(1, Math.min(p, maxParallel));
}
new SCryptPasswordEncoder(cpuCost, memoryCost, p, keyLen, saltLen);

Try / catch

try {
    encoder = new SCryptPasswordEncoder(cpuCost, r, p, keyLen, saltLen);
} catch (IllegalArgumentException e) {
    encoder = new SCryptPasswordEncoder(cpuCost, r, 1, keyLen, saltLen); // safe p=1
}

Prevention

When it happens

Trigger: `new SCryptPasswordEncoder(cpuCost, memoryCost, parallelization, ...)` with parallelization < 1 or > Integer.MAX_VALUE/(128*memoryCost*8).

Common situations: Passing 0 for p from a default config; unreasonably large p values copied from tuning guides without checking the bound; the message reveals the actual maxParallel so developers can clamp to it.

Related errors


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