jwtk/jjwt · error · io.jsonwebtoken.security.MalformedKeyException
JWK kty value cannot be null.
Error message
JWK kty value cannot be null.
What it means
applyFrom checks the value of the mandatory 'kty' parameter for null after confirming the key exists. A JWK whose 'kty' member is present but JSON null is malformed, so MalformedKeyException is thrown.
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/JwkConverter.java:148
throw unexpectedIAE((Jwk<?>) o);
}
if (!(o instanceof Map)) {
String msg = "JWK must be a Map<String,?> (JSON Object). Type found: " + o.getClass().getName() + ".";
throw new IllegalArgumentException(msg);
}
final Map<?, ?> map = Collections.immutable((Map<?, ?>) o);
Parameter<String> param = AbstractJwk.KTY;
// mandatory for all JWKs: https://datatracker.ietf.org/doc/html/rfc7517#section-4.1
// no need for builder param type conversion overhead if this isn't present:
if (Collections.isEmpty(map) || !map.containsKey(param.getId())) {
String msg = "JWK is missing required " + param + " parameter.";
throw new MalformedKeyException(msg);
}
Object val = map.get(param.getId());
if (val == null) {
String msg = "JWK " + param + " value cannot be null.";
throw new MalformedKeyException(msg);
}
if (!(val instanceof String)) {
String msg = "JWK " + param + " value must be a String. Type found: " + val.getClass().getName();
throw new MalformedKeyException(msg);
}
String kty = (String) val;
if (!Strings.hasText(kty)) {
String msg = "JWK " + param + " value cannot be empty.";
throw new MalformedKeyException(msg);
}
DynamicJwkBuilder<?, ?> builder = this.supplier.get();
for (Map.Entry<?, ?> entry : map.entrySet()) {
Object key = entry.getKey();
Assert.notNull(key, "JWK map key cannot be null.");
if (!(key instanceof String)) {
String msg = "JWK map keys must be Strings. Encountered key '" + key + "' of type " +
key.getClass().getName() + ".";View on GitHub (pinned to fb71496164)
Solutions
- Provide a non-null "kty" value such as "RSA", "EC", "oct", or "OKP"
- Sanitize the JSON before parsing to remove null-valued fields
- Log/inspect the source of the key data to find where the null originates
Example fix
// before
{"kty": null, "n": "...", "e": "AQAB"}
// after
{"kty": "RSA", "n": "...", "e": "AQAB"} Defensive patterns
Strategy: validation
Validate before calling
Object kty = jwkMap.get("kty"); if (kty == null) { throw new IllegalArgumentException("JWK 'kty' must not be null"); } Type guard
boolean hasNonNullKty(Map<String,?> m) { return m != null && m.get("kty") != null; } Try / catch
try { jwk = jwkParser.parse(map); } catch (MalformedKeyException e) { log.error("JWK rejected: {}", e.getMessage()); } Prevention
- Strip null-valued members before passing JWK maps to jjwt
- Fill kty programmatically when constructing keys in code
When it happens
Trigger: Parsing JWK JSON like {"kty": null, ...} or building a JWK from a map where kty maps to null.
Common situations: Deserialization frameworks or template-generated JSON that emit explicit nulls; partial key material filled in programmatically.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- JWK is missing required kty parameter.
- JWK kty value cannot be empty.
- JWK Set keys value cannot be null.
- RSA JWK 'oth' (Other Prime Info) element cannot be null.
- ${name()} is missing required ${param} value.
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/20e57a16286cc155.
Report an issue: GitHub.