spring-projects/spring-security · error · IllegalArgumentException
Memory cost must be >= 1.
Error message
Memory cost must be >= 1.
What it means
The memoryCost (r) parameter of scrypt is the block size and must be at least 1. SCryptPasswordEncoder validates this in its 5-arg constructor and throws IllegalArgumentException when r < 1, because scrypt cannot operate with a zero or negative block size.
Source
Thrown at crypto/src/main/java/org/springframework/security/crypto/scrypt/SCryptPasswordEncoder.java:105
* @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;
this.keyLength = keyLength;
this.saltGenerator = KeyGenerators.secureRandom(saltLength);
}View on GitHub (pinned to 96852e8860)
Solutions
- Pass memoryCost >= 1 (the library default is 8).
- Validate/parse the config value before constructing the encoder.
- Use the no-arg SCryptPasswordEncoder() to accept secure defaults.
Example fix
// before new SCryptPasswordEncoder(16384, 0, 1, 32, 64); // after new SCryptPasswordEncoder(16384, 8, 1, 32, 64);
Defensive patterns
Strategy: validation
Validate before calling
if (memoryCost < 1) {
throw new IllegalArgumentException("memoryCost (r) must be >= 1: " + memoryCost);
}
new SCryptPasswordEncoder(cpuCost, memoryCost, p, keyLen, saltLen); Try / catch
try {
encoder = new SCryptPasswordEncoder(cpuCost, r, p, keyLen, saltLen);
} catch (IllegalArgumentException e) {
encoder = new SCryptPasswordEncoder();
} Prevention
- Default r to 8 when config value is absent/0.
- Don't swap r and p argument positions.
- Assert config values after parsing.
When it happens
Trigger: `new SCryptPasswordEncoder(cpuCost, memoryCost, ...)` with memoryCost < 1 (0 or negative).
Common situations: Reading parameters from config/properties files where r defaults to 0 when unset; integer parse failures coerced to 0; typos swapping r and p arguments.
Related errors
- Cpu cost parameter must be > 1 and < 65536.
- Parallelisation parameter p must be >= 1 and <= {maxParallel
- Key length must be >= 1 and <= {Integer.MAX_VALUE}
- Salt length must be >= 1 and <= {Integer.MAX_VALUE}
- Invalid encoded Argon2-hash
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/2fdc4a8e279493df.
Report an issue: GitHub.