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

  1. Request a derivedKeyBitLength <= MAX_DERIVED_KEY_BIT_LENGTH (check ConcatKDF.MAX_DERIVED_KEY_BIT_LENGTH).
  2. If you need larger keys, derive multiple keys or chain KDFs deliberately.
  3. Confirm you passed bits, not bytes (multiply byte length by 8 correctly, e.g. 256 not 32).
  4. 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

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


AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09). Data as JSON: /api/errors/ae0e7d0c0682e047. Report an issue: GitHub.