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

  1. Ensure the input to hashpw is a complete bcrypt hash like '$2a$10$<22-char-salt>' so the derived salt length is positive
  2. Validate the hash format with a regex (e.g. \\A\\$2(a|y|b)?\\$\\d{2}\\$[./A-Za-z0-9]{53}) before parsing
  3. 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

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


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