{"record":{"id":"f084c8c01653df23","repo":"spring-projects/spring-security","slug":"salt-length-must-be-1-and-integer-max-value","errorCode":null,"errorMessage":"Salt length must be >= 1 and <= {Integer.MAX_VALUE}","messagePattern":"Salt length must be >= 1 and <= (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"crypto/src/main/java/org/springframework/security/crypto/scrypt/SCryptPasswordEncoder.java","lineNumber":116,"sourceCode":"\t\tif (cpuCost <= 1) {\n\t\t\tthrow new IllegalArgumentException(\"Cpu cost parameter must be > 1.\");\n\t\t}\n\t\tif (memoryCost == 1 && cpuCost > 65536) {\n\t\t\tthrow new IllegalArgumentException(\"Cpu cost parameter must be > 1 and < 65536.\");\n\t\t}\n\t\tif (memoryCost < 1) {\n\t\t\tthrow new IllegalArgumentException(\"Memory cost must be >= 1.\");\n\t\t}\n\t\tint maxParallel = Integer.MAX_VALUE / (128 * memoryCost * 8);\n\t\tif (parallelization < 1 || parallelization > maxParallel) {\n\t\t\tthrow new IllegalArgumentException(\"Parallelisation parameter p must be >= 1 and <= \" + maxParallel\n\t\t\t\t\t+ \" (based on block size r of \" + memoryCost + \")\");\n\t\t}\n\t\tif (keyLength < 1 || keyLength > Integer.MAX_VALUE) {\n\t\t\tthrow new IllegalArgumentException(\"Key length must be >= 1 and <= \" + Integer.MAX_VALUE);\n\t\t}\n\t\tif (saltLength < 1 || saltLength > Integer.MAX_VALUE) {\n\t\t\tthrow new IllegalArgumentException(\"Salt length must be >= 1 and <= \" + Integer.MAX_VALUE);\n\t\t}\n\t\tthis.cpuCost = cpuCost;\n\t\tthis.memoryCost = memoryCost;\n\t\tthis.parallelization = parallelization;\n\t\tthis.keyLength = keyLength;\n\t\tthis.saltGenerator = KeyGenerators.secureRandom(saltLength);\n\t}\n\n\t/**\n\t * Constructs a SCrypt password encoder with cpu cost of 16,384, memory cost of 8,\n\t * parallelization of 1, a key length of 32 and a salt length of 64 bytes.\n\t * @return the {@link SCryptPasswordEncoder}\n\t * @since 5.8\n\t * @deprecated Use {@link #defaultsForSpringSecurity_v5_8()} instead\n\t */\n\t@Deprecated\n\tpublic static SCryptPasswordEncoder defaultsForSpringSecurity_v4_1() {\n\t\treturn new SCryptPasswordEncoder(16384, 8, 1, 32, 64);","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/crypto/src/main/java/org/springframework/security/crypto/scrypt/SCryptPasswordEncoder.java#L98-L134","documentation":"The salt length must be at least 1 (and, per the message, within int range). SCryptPasswordEncoder builds a secure-random generator of exactly saltLength bytes; a saltLength < 1 would produce no salt, so the constructor throws IllegalArgumentException.","triggerScenarios":"`new SCryptPasswordEncoder(cpuCost, memoryCost, parallelization, keyLength, saltLength)` with saltLength < 1 (0 or negative).","commonSituations":"saltLength sourced from configuration defaulting to 0 when the property is missing; copying call sites and misordering the last two arguments; assuming 0 means 'use default'.","solutions":["Pass a positive saltLength in bytes (e.g. 64, the library default).","Check the config property is present and >= 1 before constructing.","Use the no-arg SCryptPasswordEncoder() for default salt handling."],"exampleFix":"// before\nnew SCryptPasswordEncoder(16384, 8, 1, 32, 0);\n// after\nnew SCryptPasswordEncoder(16384, 8, 1, 32, 64);","handlingStrategy":"validation","validationCode":"if (saltLength < 1) {\n    throw new IllegalArgumentException(\"saltLength must be >= 1: \" + saltLength);\n}\nnew SCryptPasswordEncoder(cpuCost, memoryCost, p, keyLen, saltLength);","typeGuard":null,"tryCatchPattern":"try {\n    encoder = new SCryptPasswordEncoder(cpuCost, r, p, keyLen, saltLen);\n} catch (IllegalArgumentException e) {\n    encoder = new SCryptPasswordEncoder(); // default salt length 64\n}","preventionTips":["Use 64-byte salts (library default).","Check the config property exists before use.","Don't pass 0 meaning 'auto'."],"tags":["java","spring-security","password-hashing","validation","salt"],"backgroundTag":"argument-out-of-range","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}