jwtk/jjwt · error · io.jsonwebtoken.security.SecurityException
${Class} callback execution failed: ${t.getMessage()}
Error message
${Class} callback execution failed: ${t.getMessage()} What it means
JcaTemplate wraps JCE operations (Cipher, KeyFactory, SecretKeyFactory, KeyGenerator) in callback functions. Any Throwable thrown inside a callback other than SecurityException is wrapped into a SecurityException with this message naming the JCE class, preserving the cause. It signals that the underlying JCE call failed — e.g. bad algorithm parameters, unsupported provider, or invalid key material.
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/JcaTemplate.java:123
private <T, R> R execute(Class<T> clazz, CheckedFunction<T, R> callback, Provider provider) throws Exception {
InstanceFactory<?> factory = REGISTRY.get(clazz);
Assert.notNull(factory, "Unsupported JCA instance class.");
Object object = factory.get(this.jcaName, provider);
T instance = Assert.isInstanceOf(clazz, object, "Factory instance does not match expected type.");
return callback.apply(instance);
}
private <T> T execute(Class<?> clazz, CheckedSupplier<T> fn) throws SecurityException {
try {
return fn.get();
} catch (SecurityException se) {
throw se; //propagate
} catch (Throwable t) {
String msg = clazz.getSimpleName() + " callback execution failed: " + t.getMessage();
throw new SecurityException(msg, t);
}
}
private <T, R> R execute(final Class<T> clazz, final CheckedFunction<T, R> fn) throws SecurityException {
return execute(clazz, new CheckedSupplier<R>() {
@Override
public R get() throws Exception {
return execute(clazz, fn, JcaTemplate.this.provider);
}
});
}
protected <T, R> R fallback(final Class<T> clazz, final CheckedFunction<T, R> callback) throws SecurityException {
return execute(clazz, new CheckedSupplier<R>() {
@Override
public R get() throws Exception {
try {
return execute(clazz, callback, JcaTemplate.this.provider);View on GitHub (pinned to fb71496164)
Solutions
- Inspect the exception's cause (`e.getCause()`) — it holds the original JCE error (NoSuchAlgorithmException, InvalidKeySpecException, AEADBadTagException, etc.).
- Install/verify the required JCE provider (e.g. BouncyCastle) and register it before the operation.
- Confirm the algorithm name and key type match what the callback requests.
- Upgrade the JDK if the required algorithm is only available in newer versions.
Example fix
// before: no BC provider registered JweParser p = Jwts.parser().decryptWith(key).build(); // after Security.addProvider(new BouncyCastleProvider()); JweParser p = Jwts.parser().decryptWith(key).build();
Defensive patterns
Strategy: try-catch
Try / catch
try {
byte[] out = jcaTemplate.withCipher(cipherCallback);
} catch (SecurityException e) {
Throwable jceCause = e.getCause(); // real JCE failure (NoSuchAlgorithmException, etc.)
logger.error("JCE operation failed", jceCause);
} Prevention
- Always inspect getCause() — the wrapped JCE exception is the actionable error
- Register required providers (e.g. BouncyCastle) at startup
- Pin a JDK that supports the algorithms you use
- Test crypto paths early in CI on the target JDK
When it happens
Trigger: Any jjwt crypto operation whose underlying JCE call fails: Cipher.doFinal/init throwing (invalid key spec, bad block sizes, AEADBadTagException), KeyFactory.generatePublic/Private with malformed key specs, SecretKeyFactory failures, or a required algorithm/provider missing so NoSuchAlgorithmException occurs.
Common situations: Missing JCE provider for an algorithm (e.g. no provider for a specific EC curve or AES-KW); key bytes that don't match the expected KeySpec; JDK restrictions or a typo'd algorithm; wrapping a JCE exception whose cause is the real problem.
Related errors
- Nesting not permitted.
- wrap(e, jcaName, specifiedProvider, null)
- Unable to compute ${getId()} signature with JCA algorithm '$
- Invalid AES key length: ${bitsMsg(keyBitLength)}. AES only s
- wrap(nsa, jcaName, specifiedProvider, null)
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/47a152dc80ab5e43.
Report an issue: GitHub.