jwtk/jjwt · error · InvalidKeyException
Unable to create ${type.getSimpleName()} from JWK ${ctx}: ${
Error message
Unable to create ${type.getSimpleName()} from JWK ${ctx}: ${e.getMessage()} What it means
AbstractFamilyJwkFactory.apply wraps exceptions thrown while converting a JWK context into a typed Jwk/Key. Any non-KeyException failure becomes an InvalidKeyException prefixed with the target type and JWK context summary. It indicates malformed or inconsistent JWK fields that broke key reconstruction.
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/AbstractFamilyJwkFactory.java:94
protected String getKeyFactoryJcaName(final JwkContext<?> ctx) {
String jcaName = KeysBridge.findAlgorithm(ctx.getKey());
return Strings.hasText(jcaName) ? jcaName : getId();
}
protected <T extends Key> T generateKey(final JwkContext<?> ctx, final Class<T> type, final CheckedFunction<KeyFactory, T> fn) {
String jcaName = getKeyFactoryJcaName(ctx);
JcaTemplate template = new JcaTemplate(jcaName, ctx.getProvider(), ctx.getRandom());
return template.withKeyFactory(new CheckedFunction<KeyFactory, T>() {
@Override
public T apply(KeyFactory instance) {
try {
return fn.apply(instance);
} catch (KeyException keyException) {
throw keyException; // propagate
} catch (Exception e) {
String msg = "Unable to create " + type.getSimpleName() + " from JWK " + ctx + ": " + e.getMessage();
throw new InvalidKeyException(msg, e);
}
}
});
}
@Override
public final J createJwk(JwkContext<K> ctx) {
Assert.notNull(ctx, "JwkContext argument cannot be null.");
if (!supports(ctx)) { //should be asserted by caller, but assert just in case:
String msg = "Unsupported JwkContext.";
throw new IllegalArgumentException(msg);
}
K key = ctx.getKey();
if (key != null) {
ctx.setType(this.ktyValue);
return createJwkFromKey(ctx);
} else {
return createJwkFromValues(ctx);View on GitHub (pinned to fb71496164)
Solutions
- Validate that all JWK fields are valid base64url strings of the expected length for the curve/modulus.
- Confirm the 'kty' matches the concrete builder used (e.g. ECPublicJwkBuilder for EC keys).
- Catch InvalidKeyException and log the wrapped cause (e.getCause()) for the underlying failure.
- Regenerate or re-export the key if the material is corrupt.
Example fix
// before
try { Jwk<?> jwk = Jwks.parser().build().parse(json); }
catch (Exception e) { log.error(e.getMessage()); }
// after
try { Jwk<?> jwk = Jwks.parser().build().parse(json); }
catch (InvalidKeyException e) { log.error("JWK invalid", e.getCause()); } Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check base64url decodability of JWK fields
Base64.getUrlDecoder().decode(jwk.getString("n")); Try / catch
try { Jwk<?> jwk = factory.apply(ctx); }
catch (InvalidKeyException e) { log.error("JWK {} invalid: {}", e.getMessage(), e.getCause()); } Prevention
- Validate JWK fields against the RFC 7518 schema before building.
- Ensure kty matches the concrete builder.
- Round-trip test keys through parse/build in CI.
- Log the cause chain, not just the message.
When it happens
Trigger: Calling Jwks.builder().build() or parsing a JWK where an arithmetic/decoding error occurs inside the type-specific factory (e.g. base64url-decoded coordinates of the wrong length, BigInteger conversion failures).
Common situations: JWK JSON with truncated or non-base64url 'n'/'e'/'x'/'y' values; mismatched kty vs fields; copying keys between systems corrupting values.
Related errors
- Value must be ${articleFor(desired)} ${desired}, not ${artic
- Unrecognized JWA EC curve id '${jwaCurveId}'
- Unsupported JwkContext.
- JWKs are immutable and may not be modified.
- A ${Key.class.getName()} or one or more name/value pairs mus
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/8101432dd8faf82e.
Report an issue: GitHub.