jwtk/jjwt · error · UnsupportedOperationException

getEncoded() is disabled for Password instances as they are…

Error message

getEncoded() is disabled for Password instances as they are intended to be used with key derivation algorithms only. Because passwords rarely have the length or entropy necessary for secure cryptographic operations such as authenticated hashing or encryption, they are disabled as direct inputs for these operations to help avoid accidental misuse; if you see this exception message, it is likely that the associated Password instance is being used incorrectly.

What it means

Password implements Key but deliberately disables getEncoded(): passwords must only feed password-based key-derivation functions (e.g. PBKDF2), not be used directly as raw key material for hashing or encryption. Calling getEncoded() throws UnsupportedOperationException with this long explanatory message.

Solutions

  1. Derive an actual key first, e.g. via Jwts.SIG.PBES2-HS256+A128KW for JWE, or Keys.builder(password)... / SecretKeyFactory PBKDF2, then use the derived SecretKey.
  2. Use the Password only with password-based algorithms that accept char[] input.
  3. Refactor helper code that assumes Key.getEncoded() is always available.

Example fix

// before
cipher.init(Cipher.ENCRYPT_MODE, password);
// after
SecretKey derived = Jwts.SIG.PBES2_HS256_A128KW.key(new SecureRandom())
    ... // or use KDF
SecretKey k = Keys.password(pwdChars).derive(...);
Defensive patterns

Strategy: try-catch

Validate before calling

if (key instanceof Password) {
    throw new IllegalArgumentException("Use a derived SecretKey, not a raw Password, here");
}

Type guard

boolean isDerivedKey(Key k) { return k instanceof SecretKey && !(k instanceof Password); }

Try / catch

try {
    cipher.init(Cipher.ENCRYPT_MODE, key);
} catch (UnsupportedOperationException e) {
    // Password used where only derived keys are allowed
}

Prevention

When it happens

Trigger: Passing a Password instance where a regular encoded Key is expected — e.g. encrypting/hashing directly with the password, serializing it, or handing it to APIs that call getEncoded().

Common situations: Using a password directly with a cipher/MAC instead of deriving a key via a PBES2 algorithm; generic code that inspects key.getEncoded() for logging or key comparison.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/PasswordSpec.java:68

    @Override
    public char[] toCharArray() {
        assertActive();
        return this.password.clone();
    }

    @Override
    public String getAlgorithm() {
        return NONE_ALGORITHM;
    }

    @Override
    public String getFormat() {
        return null; // encoding isn't supported, so we return null per the Key#getFormat() JavaDoc
    }

    @Override
    public byte[] getEncoded() {
        throw new UnsupportedOperationException(ENCODED_DISABLED_MSG);
    }

    public void destroy() {
        this.destroyed = true;
        java.util.Arrays.fill(password, '\u0000');
    }

    public boolean isDestroyed() {
        return this.destroyed;
    }

    @Override
    public int hashCode() {
        return Objects.nullSafeHashCode(this.password);
    }

    @Override
    public boolean equals(Object obj) {

View on GitHub (pinned to fb71496164)