jwtk/jjwt · error · IllegalArgumentException
derivedKeyBitLength may not exceed ${bitsMsg(MAX_DERIVED_KEY
Error message
derivedKeyBitLength may not exceed ${bitsMsg(MAX_DERIVED_KEY_BIT_LENGTH)}. Specified size: ${bitsMsg(derivedKeyBitLength)}. What it means
IllegalArgumentException from ConcatKDF.deriveKey when the requested derived key bit length exceeds MAX_DERIVED_KEY_BIT_LENGTH (the library's safety ceiling for NIST SP 800-56A Concat KDF output). The KDF will not produce keys longer than this bound.
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/ConcatKDF.java:95
* @param otherInfo any additional party info to be associated with the derived key. May be null/empty.
* @return the derived key
* @throws UnsupportedKeyException if unable to obtain {@code sharedSecretKey}'s
* {@link Key#getEncoded() encoded byte array}.
* @throws SecurityException if unable to perform the necessary {@link MessageDigest} computations to
* generate the derived key.
*/
public SecretKey deriveKey(final byte[] Z, final long derivedKeyBitLength, final byte[] otherInfo)
throws UnsupportedKeyException, SecurityException {
// sharedSecretKey argument assertions:
Assert.notEmpty(Z, "Z cannot be null or empty.");
// derivedKeyBitLength argument assertions:
Assert.isTrue(derivedKeyBitLength > 0, "derivedKeyBitLength must be a positive integer.");
if (derivedKeyBitLength > MAX_DERIVED_KEY_BIT_LENGTH) {
String msg = "derivedKeyBitLength may not exceed " + bitsMsg(MAX_DERIVED_KEY_BIT_LENGTH) +
". Specified size: " + bitsMsg(derivedKeyBitLength) + ".";
throw new IllegalArgumentException(msg);
}
final long derivedKeyByteLength = derivedKeyBitLength / Byte.SIZE;
final byte[] OtherInfo = otherInfo == null ? EMPTY : otherInfo;
// Section 5.8.1.1, Process step #1:
final double repsd = derivedKeyBitLength / (double) this.hashBitLength;
final long reps = (long) Math.ceil(repsd);
// If repsd didn't result in a whole number, the last derived key byte will be partially filled per
// Section 5.8.1.1, Process step #6:
final boolean kLastPartial = repsd != (double) reps;
// Section 5.8.1.1, Process step #2:
Assert.state(reps <= MAX_REP_COUNT, "derivedKeyBitLength is too large.");
// Section 5.8.1.1, Process step #3:
final byte[] counter = new byte[]{0, 0, 0, 1}; // same as 0x0001L, but no extra step to convert to byte[]
View on GitHub (pinned to fb71496164)
Solutions
- Request a derivedKeyBitLength <= MAX_DERIVED_KEY_BIT_LENGTH (check ConcatKDF.MAX_DERIVED_KEY_BIT_LENGTH).
- If you need larger keys, derive multiple keys or chain KDFs deliberately.
- Confirm you passed bits, not bytes (multiply byte length by 8 correctly, e.g. 256 not 32).
- Ensure the value is positive; zero/negative is rejected by the preceding Assert.isTrue.
Example fix
// before ConcatKDF kdf = new ConcatKDF(jcaDigest); SecretKey k = kdf.deriveKey(info, sharedSecret, 8192); // exceeds max // after SecretKey k = kdf.deriveKey(info, sharedSecret, 256); // within MAX_DERIVED_KEY_BIT_LENGTH
Defensive patterns
Strategy: validation
Validate before calling
static void checkDerivedLength(int derivedKeyBitLength) {
if (derivedKeyBitLength <= 0 || derivedKeyBitLength > ConcatKDF.MAX_DERIVED_KEY_BIT_LENGTH)
throw new IllegalArgumentException("derivedKeyBitLength out of range");
} Try / catch
try {
return kdf.deriveKey(info, sharedSecret, bitLen);
} catch (IllegalArgumentException e) {
throw new IllegalStateException("Unsupported derived key length: " + bitLen, e);
} Prevention
- Read ConcatKDF.MAX_DERIVED_KEY_BIT_LENGTH before choosing a size
- Pass bits, not bytes (256 for a 32-byte key)
- Clamp or wrap requested lengths in a helper before calling deriveKey
When it happens
Trigger: Calling ConcatKDF.deriveKey(relatedData, keyBytes, derivedKeyBitLength) with a derivedKeyBitLength larger than the library maximum (must also be a positive multiple representable as bytes).
Common situations: Custom key-derivation code requesting, say, 4096-bit derived keys; porting code that used another KDF without length caps; miscomputing bit length by passing byte counts instead of bit counts.
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
- Unexpected content JWE.
- Unexpected Claims JWE.
- The '${id}' algorithm requires keys with a length of ${bitsM
- The '${id}' algorithm requires ${type} with a length of ${bi
- Passwords are intended for use with key derivation algorithm
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/ae0e7d0c0682e047.
Report an issue: GitHub.