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
- Read the cause to identify the provider-level failure and check the key's provider logs.
- Use a software key (KeyGenerator/KeyFactory) when the operation requires exported bytes.
- For HSM keys, perform signing/verification inside the token instead of extracting bytes, using provider-specific APIs.
- 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
- Test key.getEncoded() early at startup for any key you plan to use with jjwt.
- Prefer software-generated keys for MAC/AES-based jjwt operations.
- Document that HSM/smartcard keys may not be exportable and design around provider-side crypto.
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
- Missing required encoded bytes for key [${toString(key)}].
- Unable to determine a suitable MAC or Signature algorithm fo
- JWK Set map keys must be Strings. Encountered key '${key}' o
- JWK Set keys[${i}]: ${e.getMessage()}
- Malformed JWK Set JSON: ${t.getMessage()}
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/11d5a8b205e5567d.
Report an issue: GitHub.