jwtk/jjwt · error · IllegalArgumentException
bitLength argument must be >= 0
Error message
bitLength argument must be >= 0
What it means
Bytes.length(bitLength) computes the minimum number of bytes needed to represent a given number of bits and validates that the input is not negative, throwing IllegalArgumentException otherwise. It is a pure size utility used when sizing keys/byte arrays.
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/lang/Bytes.java:224
* Returns the minimum number of bytes required to represent the specified number of bits.
*
* <p>This is defined/used by many specifications, such as:</p>
* <ul>
* <li><a href="https://www.rfc-editor.org/rfc/rfc7518.html#section-2">JWA RFC 7518, Section 2</a>'s
* <code>Base64urlUInt</code> definition</li>
* <li>Elliptic Curve <code>Integer-to-OctetString</code> conversion defined by Section 2.3.7 of the
* <a href="http://www.secg.org/sec1-v2.pdf">Standards for Efficient Cryptography Group,
* &qupt;SEC 1: Elliptic Curve Cryptography" Version 2.0, May 2009</a> (as required by
* <a href="https://www.rfc-editor.org/rfc/rfc7518.html#section-3.4">RFC 7518, Section 3.4</a>)</li>
* <li>and others.</li>
* </ul>
*
* @param bitLength the number of bits to represent as a byte array, must be >= 0
* @return the minimum number of bytes required to represent the specified number of bits.
* @throws IllegalArgumentException if {@code bitLength} is less than zero.
*/
public static int length(int bitLength) {
if (bitLength < 0) throw new IllegalArgumentException("bitLength argument must be >= 0");
return (bitLength + 7) / Byte.SIZE;
}
public static String bitsMsg(long bitLength) {
return bitLength + " bits (" + bitLength / Byte.SIZE + " bytes)";
}
public static String bytesMsg(int byteArrayLength) {
return bitsMsg((long) byteArrayLength * Byte.SIZE);
}
public static void increment(byte[] a) {
for (int i = a.length - 1; i >= 0; --i) {
if (++a[i] != 0) {
break;
}
}
}View on GitHub (pinned to fb71496164)
Solutions
- Clamp or validate before the call: if (bitLength < 0) throw/defaults.
- Fix the source of the negative number - usually an unset config value or a bad subtraction.
- Use a positive constant (e.g. 256 for a 256-bit key) instead of derived values where possible.
Example fix
// before
int bytes = Bytes.length(keyBits - overheadBits); // can go negative
// after
int bits = Math.max(keyBits - overheadBits, 0);
if (bits <= 0) throw new IllegalStateException("key size underflow");
int bytes = Bytes.length(bits); Defensive patterns
Strategy: validation
Validate before calling
if (bitLength < 0) {
throw new IllegalArgumentException("bitLength must be >= 0, got " + bitLength);
}
int bytes = Bytes.length(bitLength); Try / catch
try {
int len = Bytes.length(bits);
} catch (IllegalArgumentException e) {
// log and use configured default key size
} Prevention
- Sanity-check derived sizes: use Math.max(0, computed)
- Fail fast on unset config values instead of using -1 sentinels
- Prefer explicit constants for key sizes
When it happens
Trigger: Calling Bytes.length(negativeBitLength), typically when the bit length came from a misconfigured key size, a failed parse (Integer.parseInt of bad input producing unexpected math), or an arithmetic result that underflowed.
Common situations: Key-size configuration read as negative (e.g. '-1' default when unset); subtracting header overhead from a size and going below zero; computing bit length of an empty/missing value.
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
- numBytes argument must be >= 0
- constant [%s] does not exist in enum type %s
- Values must be either String or ${type.getName()} instances.
- bitLength must be an even multiple of 8
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/62aca667ae982d29.
Report an issue: GitHub.