spring-projects/spring-security · error · IllegalArgumentException
Invalid maxolen
Error message
Invalid maxolen
What it means
BCrypt.decode_base64() decodes bcrypt-alphabet strings into at most maxolen bytes. It throws this IllegalArgumentException when maxolen <= 0, because a non-positive output length is meaningless. Called from hashpw when parsing the salt portion of a bcrypt hash string.
Source
Thrown at crypto/src/main/java/org/springframework/security/crypto/bcrypt/BCrypt.java:285
return index_64[x];
}
/**
* Decode a string encoded using bcrypt's base64 scheme to a byte array. Note that
* this is *not* compatible with the standard MIME-base64 encoding.
* @param s the string to decode
* @param maxolen the maximum number of bytes to decode
* @return an array containing the decoded bytes
* @throws IllegalArgumentException if maxolen is invalid
*/
static byte[] decode_base64(String s, int maxolen) throws IllegalArgumentException {
StringBuilder rs = new StringBuilder();
int off = 0, slen = s.length(), olen = 0;
byte ret[];
byte c1, c2, c3, c4, o;
if (maxolen <= 0) {
throw new IllegalArgumentException("Invalid maxolen");
}
while (off < slen - 1 && olen < maxolen) {
c1 = char64(s.charAt(off++));
c2 = char64(s.charAt(off++));
if (c1 == -1 || c2 == -1) {
break;
}
o = (byte) (c1 << 2);
o |= (c2 & 0x30) >> 4;
rs.append((char) o);
if (++olen >= maxolen || off >= slen) {
break;
}
c3 = char64(s.charAt(off++));
if (c3 == -1) {
break;
}View on GitHub (pinned to 96852e8860)
Solutions
- Ensure the input to hashpw is a complete bcrypt hash like '$2a$10$<22-char-salt>' so the derived salt length is positive
- Validate the hash format with a regex (e.g. \\A\\$2(a|y|b)?\\$\\d{2}\\$[./A-Za-z0-9]{53}) before parsing
- If calling decode_base64 directly, pass a maxolen >= 1 and <= expected output size
Example fix
// before
byte[] salt = BCrypt.decode_base64(saltPart, 0); // maxolen <= 0
// after
if (saltPart.length() < 22) throw new IllegalArgumentException("salt too short");
byte[] salt = BCrypt.decode_base64(saltPart, 16); Defensive patterns
Strategy: validation
Validate before calling
static boolean isBcryptHashFormat(String s) {
return s != null && s.matches("\\\\A\\\\$2(a|y|b)?\\\\$\\\\d{2}\\\\$[./A-Za-z0-9]{53}\\\\z");
} Try / catch
try {
return BCrypt.hashpw(raw, storedHash);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("maxolen")) {
log.warn("Malformed bcrypt hash: salt segment too short");
return false;
}
throw e;
} Prevention
- Regex-validate stored bcrypt hashes before calling hashpw for verification
- Never truncate or trim hash strings in transit (avoid lossy charsets/trimming)
- Pass full hashes to BCrypt.checkpw rather than extracting segments manually
When it happens
Trigger: Calling decode_base64 (directly or via hashpw) with maxolen <= 0 — e.g. parsing a hash string where the computed salt length came out as 0 because the input hash string was malformed or empty.
Common situations: Passing a malformed/empty salt string to hashpw(); truncation of stored hashes; manual parsing of bcrypt strings producing a wrong length.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Invalid len
- Bad number of rounds
- Invalid encoded Argon2-hash
- Amount of performance parameters invalid
- Invalid memory parameter
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/029ba76e02810cef.
Report an issue: GitHub.