jwtk/jjwt · error · IllegalArgumentException
Byte array must be exactly ${bitsMsg(this.bitLength)}. Found
Error message
Byte array must be exactly ${bitsMsg(this.bitLength)}. Found ${bitsMsg(len)} What it means
RequiredBitLengthConverter.assertLength enforces that a byte array has an exact bit length when the converter was created with exact=true. If Bytes.bitLength(bytes) differs from the configured bitLength, this IllegalArgumentException reports the required and found sizes (via Bytes.bitsMsg).
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/lang/RequiredBitLengthConverter.java:41
private final int bitLength;
private final boolean exact;
public RequiredBitLengthConverter(Converter<byte[], Object> converter, int bitLength) {
this(converter, bitLength, true);
}
public RequiredBitLengthConverter(Converter<byte[], Object> converter, int bitLength, boolean exact) {
this.converter = Assert.notNull(converter, "Converter cannot be null.");
this.bitLength = Assert.gt(bitLength, 0, "bitLength must be greater than 0");
this.exact = exact;
}
private byte[] assertLength(byte[] bytes) {
long len = Bytes.bitLength(bytes);
if (exact && len != this.bitLength) {
String msg = "Byte array must be exactly " + Bytes.bitsMsg(this.bitLength) + ". Found " + Bytes.bitsMsg(len);
throw new IllegalArgumentException(msg);
} else if (len < this.bitLength) {
String msg = "Byte array must be at least " + Bytes.bitsMsg(this.bitLength) + ". Found " + Bytes.bitsMsg(len);
throw new IllegalArgumentException(msg);
}
return bytes;
}
@Override
public Object applyTo(byte[] bytes) {
assertLength(bytes);
return this.converter.applyTo(bytes);
}
@Override
public byte[] applyFrom(Object o) {
byte[] result = this.converter.applyFrom(o);
return assertLength(result);
}View on GitHub (pinned to fb71496164)
Solutions
- Generate or resize the byte array to the exact required length (e.g. 16 bytes for 128 bits).
- Use Keys.secretKeyFor(SignatureAlgorithm) or a proper key generator instead of hand-built arrays.
- Verify with bytes.length * 8 == requiredBits before calling the API.
Example fix
// before byte[] key = new byte[15]; // 120 bits // after byte[] key = new byte[16]; // exactly 128 bits
Defensive patterns
Strategy: validation
Validate before calling
void requireExactBits(byte[] b, long bits) {
long len = b.length * 8L; // approximate; matches Bytes.bitLength semantics
if (len != bits) throw new IllegalArgumentException("Need exactly " + bits + " bits, got " + len);
} Try / catch
try {
converter.applyTo(bytes);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Byte array must be exactly")) {
// regenerate/resize the byte array
}
throw e;
} Prevention
- Generate keys with Keys.secretKeyFor() or SecureRandom of the right size
- Assert byte-array length in bits before using cryptographic claims
- Don't trim or pad key material manually
When it happens
Trigger: Providing a key/byte-array parameter (e.g. a 128-bit key claim) whose length in bits is not exactly the required amount, such as a 120-bit array where 128 bits is exact-required.
Common situations: Manually generated keys of the wrong size; keys trimmed or padded by other tooling; base64url-decoding inputs that lost bytes.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Byte array must be at least ${bitsMsg(this.bitLength)}. Foun
- ${i.getClass()} getId() cannot be null or empty.
- Value must be a positive integer.
- Unsupported value type. Expected: ${type.getName()}, found:
- Invalid AES key length: ${bitsMsg(keyBitLength)}. AES only s
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/91df18740f8aafb6.
Report an issue: GitHub.