spring-projects/spring-security · error · IllegalArgumentException
Invalid len
Error message
Invalid len
What it means
BCrypt.encode_base64() encodes len bytes of d into bcrypt's custom base64 alphabet. It throws this IllegalArgumentException when len is <= 0 or exceeds d.length, i.e. when asked to encode zero bytes or more bytes than the array holds. This is an internal-argument sanity check protecting against buffer overreads.
Source
Thrown at crypto/src/main/java/org/springframework/security/crypto/bcrypt/BCrypt.java:231
private int P[] = new int[0];
private int S[] = new int[0];
/**
* Encode a byte array using bcrypt's slightly-modified base64 encoding scheme. Note
* that this is <strong>not</strong> compatible with the standard MIME-base64
* encoding.
* @param d the byte array to encode
* @param len the number of bytes to encode
* @param rs the destination buffer for the base64-encoded string
* @exception IllegalArgumentException if the length is invalid
*/
static void encode_base64(byte d[], int len, StringBuilder rs) throws IllegalArgumentException {
int off = 0;
int c1, c2;
if (len <= 0 || len > d.length) {
throw new IllegalArgumentException("Invalid len");
}
while (off < len) {
c1 = d[off++] & 0xff;
rs.append(base64_code[(c1 >> 2) & 0x3f]);
c1 = (c1 & 0x03) << 4;
if (off >= len) {
rs.append(base64_code[c1 & 0x3f]);
break;
}
c2 = d[off++] & 0xff;
c1 |= (c2 >> 4) & 0x0f;
rs.append(base64_code[c1 & 0x3f]);
c1 = (c2 & 0x0f) << 2;
if (off >= len) {
rs.append(base64_code[c1 & 0x3f]);
break;
}View on GitHub (pinned to 96852e8860)
Solutions
- Check that the byte array passed to hashpw/gensalt is non-empty and correctly sized (salt: 16 raw bytes)
- Do not call encode_base64 directly; use the public hashpw(String, String) API
- If you forked BCrypt.java, audit the len/offset arithmetic at the call site
Example fix
// before BCrypt.encode_base64(new byte[0], 8, sb); // len > d.length // after byte[] data = Arrays.copyOf(saltBytes, 16); // ensure capacity >= len BCrypt.encode_base64(data, 16, sb);
Defensive patterns
Strategy: try-catch
Validate before calling
static boolean canEncode(byte[] d, int len) {
return len > 0 && len <= d.length;
} Type guard
if (data == null || data.length == 0) throw new IllegalArgumentException("data must be non-empty"); Try / catch
try {
BCrypt.encode_base64(data, len, sb);
} catch (IllegalArgumentException e) {
throw new IllegalStateException("encode_base64 length invariant violated: " + e.getMessage(), e);
} Prevention
- Avoid calling BCrypt internals directly; use hashpw/gensalt
- Ensure salt byte arrays are exactly 16 bytes for bcrypt
- Don't modify forked BCrypt length/offset arithmetic without tests
When it happens
Trigger: Calling encode_base64 with len <= 0 or len > d.length — typically via hashpw or gensalt with corrupted internal state, or direct calls with a wrong length argument.
Common situations: Direct use of BCrypt internals (package-private/static misuse); modified forks of BCrypt.java passing wrong offsets; empty input byte arrays reaching hashing internals.
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 maxolen
- 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/1a6b382bfbd3d7d8.
Report an issue: GitHub.