jwtk/jjwt · error · io.jsonwebtoken.security.MalformedKeyException
JWK is missing required kty parameter.
Error message
JWK is missing required kty parameter.
What it means
When converting a raw JSON map into a Jwk, JwkConverter.applyFrom requires the mandatory 'kty' (key type) parameter as defined by RFC 7517 section 4.1. If the map is empty or lacks the 'kty' key, a MalformedKeyException is thrown. This is a hard requirement for all JWKs regardless of algorithm.
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/JwkConverter.java:143
public T applyFrom(Object o) {
Assert.notNull(o, "JWK cannot be null.");
if (desiredType.isInstance(o)) {
return desiredType.cast(o);
} else if (o instanceof Jwk<?>) {
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()) {View on GitHub (pinned to fb71496164)
Solutions
- Add the required "kty" field (e.g. "EC", "RSA", "oct", "OKP") to the JWK JSON object
- Verify you are passing an individual JWK object, not a JWK Set or another structure
- If parsing a JWKS document, ensure each element of the "keys" array contains "kty"
Example fix
// before
{"k":"..."}
// after
{"kty":"oct","k":"..."} Defensive patterns
Strategy: validation
Validate before calling
if (jwkMap == null || !jwkMap.containsKey("kty")) { throw new IllegalArgumentException("JWK JSON must contain a 'kty' field"); } Type guard
boolean hasKty(Map<String,?> m) { return m != null && m.get("kty") instanceof String s && !s.isBlank(); } Try / catch
try { Jwk<?> jwk = Jwks.parser().build().parse(json); } catch (MalformedKeyException e) { log.error("Invalid JWK: {}", e.getMessage()); } Prevention
- Always include kty in every JWK you emit
- Validate key JSON against RFC 7517 before parsing
- Fetch keys from trusted, well-formed JWKS endpoints
When it happens
Trigger: Passing a JSON object/map without a 'kty' member to Jwks parsing/builder conversion APIs (e.g. io.jsonwebtoken.Jwks parsing a key that omits kty).
Common situations: Hand-written JWK JSON that omits kty; keys copied from sources that strip fields; wrong nested object passed (e.g. passing the JWK Set wrapper where an individual key is expected, or vice versa).
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 kty value cannot be null.
- JWK kty value cannot be empty.
- Missing required keys parameter.
- 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/2bde3d371b3fc422.
Report an issue: GitHub.