jwtk/jjwt · error · InvalidKeyException

Passwords are intended for use with key derivation algorithm

Error message

Passwords are intended for use with key derivation algorithms only.

What it means

InvalidKeyException from DefaultMacAlgorithm.validateKey when a jjwt Password instance is supplied to a MAC algorithm. Password objects are reserved for password-based key-derivation algorithms (e.g. PBES2) and must not be used directly as MAC keys.

Source

Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/DefaultMacAlgorithm.java:166

    }

    @Override
    protected void validateKey(Key k, boolean signing) {

        final String keyType = keyType(signing);
        if (k == null) {
            throw new IllegalArgumentException("MAC " + keyType + " key cannot be null.");
        }

        if (!(k instanceof SecretKey)) {
            String msg = "MAC " + keyType + " keys must be SecretKey instances.  Specified key is of type " +
                    k.getClass().getName();
            throw new InvalidKeyException(msg);
        }

        if (k instanceof Password) {
            String msg = "Passwords are intended for use with key derivation algorithms only.";
            throw new InvalidKeyException(msg);
        }

        final SecretKey key = (SecretKey) k;

        final String id = getId();

        assertAlgorithmName(key, signing);

        int size = KeysBridge.findBitLength(key);

        // We can only perform length validation if key bit length is available
        // per https://github.com/jwtk/jjwt/issues/478 and https://github.com/jwtk/jjwt/issues/619
        // so return early if we can't:
        if (size < 0) return;

        if (size < this.minKeyBitLength) {
            String msg = "The " + keyType + " key's size is " + size + " bits which " +
                    "is not secure enough for the " + id + " algorithm.";

View on GitHub (pinned to fb71496164)

Solutions

  1. Derive a real SecretKey from the password first, or use the PBES2 family (Jwts.SIG.PS256 with a password, or JWE PBES2 key algorithms).
  2. Convert the raw password bytes to a key: Keys.hmacShaKeyFor(derivedBytes).
  3. Pass a SecretKeySpec instead of a Password if you truly intend HMAC.
  4. Separate password handling (key derivation) from signing key handling in your code.

Example fix

// before
Password pw = Jwts.password().of(chars);
Jwts.builder().signWith(pw, Jwts.SIG.HS256);
// after
SecretKey key = Keys.hmacShaKeyFor(pw.getBytes()); // derived MAC key
Jwts.builder().signWith(key, Jwts.SIG.HS256);
Defensive patterns

Strategy: type-guard

Validate before calling

static SecretKey requireNonPassword(Key k) {
    if (k instanceof io.jsonwebtoken.security.Password)
        throw new IllegalArgumentException("Use Password only with key-derivation algorithms; derive a SecretKey for MAC");
    return (SecretKey) k;
}

Type guard

boolean isPasswordKey(Key k) { return k instanceof io.jsonwebtoken.security.Password; }

Try / catch

try {
    return Jwts.builder().signWith(key, Jwts.SIG.HS256).compact();
} catch (InvalidKeyException e) {
    if (e.getMessage().contains("key derivation algorithms only"))
        throw new IllegalStateException("Password used directly as MAC key");
    throw e;
}

Prevention

When it happens

Trigger: Calling Jwts.builder().signWith(password, HS256) where password = Jwts.password().of(...) or io.jsonwebtoken.security.Password obtained for PBKDF2/PBES2 flows.

Common situations: Using the user password object everywhere after setting up PBES2 encryption; confusing 'secret string' keys with jjwt Password wrappers; following an outdated tutorial that wraps passwords as keys.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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