jwtk/jjwt · error · InvalidKeyException

Cannot obtain required encoded bytes from key [${KeysBridge.

Error message

Cannot obtain required encoded bytes from key [${KeysBridge.toString(key)}]: ${t.getMessage()}

What it means

KeysBridge.getEncoded retrieves the platform-encoded bytes of a Key. If key.getEncoded() throws (provider error, hardware key refusing export), the method wraps it in InvalidKeyException with this message. jjwt requires the encoded bytes for many operations (e.g. deriving key material for MAC/AES keys), and a key whose provider fails during encoding is unusable.

Source

Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/KeysBridge.java:151

            bitlen = ecKey.getParams().getOrder().bitLength();
        } else {
            // We can check additional logic for EdwardsCurve even if the current JDK version doesn't support it:
            EdwardsCurve curve = EdwardsCurve.findByKey(key);
            if (curve != null) bitlen = curve.getKeyBitLength();
        }

        return bitlen;
    }

    public static byte[] getEncoded(Key key) {
        Assert.notNull(key, "Key cannot be null.");
        byte[] encoded;
        try {
            encoded = key.getEncoded();
        } catch (Throwable t) {
            String msg = "Cannot obtain required encoded bytes from key [" + KeysBridge.toString(key) + "]: " +
                    t.getMessage();
            throw new InvalidKeyException(msg, t);
        }
        if (Bytes.isEmpty(encoded)) {
            String msg = "Missing required encoded bytes for key [" + toString(key) + "].";
            throw new InvalidKeyException(msg);
        }
        return encoded;
    }

    public static String toString(Key key) {
        if (key == null) {
            return "null";
        }
        if (key instanceof PublicKey) {
            return key.toString(); // safe to show internal key state as it's a public key
        }
        // else secret or private key, don't show internal key state, just public attributes
        return "class: " + key.getClass().getName() +
                ", algorithm: " + key.getAlgorithm() +

View on GitHub (pinned to fb71496164)

Solutions

  1. Read the cause to identify the provider-level failure and check the key's provider logs.
  2. Use a software key (KeyGenerator/KeyFactory) when the operation requires exported bytes.
  3. For HSM keys, perform signing/verification inside the token instead of extracting bytes, using provider-specific APIs.
  4. Check the cause's message in the exception to see the exact provider error and consult its documentation.

Example fix

// before
SecretKey hsmKey = keystore.getKey(alias, null); // PKCS11, getEncoded throws
Jwts.builder().signWith(hsmKey); // InvalidKeyException

// after
SecretKey softwareKey = KeyGenerator.getInstance("HmacSha256").generateKey();
Jwts.builder().signWith(softwareKey); // software key with accessible encoded bytes
Defensive patterns

Strategy: try-catch

Validate before calling

boolean canExportBytes(Key key) {
    try { return key.getEncoded() != null && key.getEncoded().length > 0; }
    catch (Throwable t) { return false; }
}

Try / catch

try {
    jjwtOperation(key);
} catch (InvalidKeyException e) {
    if (e.getMessage().startsWith("Cannot obtain required encoded bytes")) {
        // swap to a software key or perform the operation inside the HSM
    } else throw e;
}

Prevention

When it happens

Trigger: Calling jjwt APIs that require encoded key bytes (e.g. Keys桥 conversions, MAC/AES key normalization) with a key whose getEncoded() throws — commonly hardware/HSM- or PKCS#11-backed keys, or keys from providers that restrict export.

Common situations: Smartcard/HSM keys where export is forbidden by security policy; Android Keystore keys that cannot be encoded; keys wrapped in custom Provider implementations with buggy getEncoded().

Related errors


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