jwtk/jjwt · error · RequiredTypeException
Cannot convert existing claim value of type '%s' to desired
Error message
Cannot convert existing claim value of type '%s' to desired type '%s'. JJWT only converts simple String, Date, Long, Integer, Short and Byte types automatically. Anything more complex is expected to be already converted to your desired type by the JSON Deserializer implementation. You may specify a custom Deserializer for a JwtParser with the desired conversion configuration via the JwtParserBuilder.deserializer() method. See https://github.com/jwtk/jjwt#custom-json-processor for more information. If using Jackson, you can specify custom claim POJO types as described in https://github.com/jwtk/jjwt#json-jackson-custom-types
What it means
castClaimValue only auto-converts simple String, Date, Long, Integer, Short and Byte claim values. If the deserialized claim is of any other type (Map, List, custom POJO, Boolean, etc.) and you request an incompatible requiredType, RequiredTypeException is thrown with this guidance message.
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/DefaultClaims.java:152
value = longValue;
} else if (Integer.class.equals(requiredType) && Integer.MIN_VALUE <= longValue && longValue <= Integer.MAX_VALUE) {
value = (int) longValue;
} else if (requiredType == Short.class && Short.MIN_VALUE <= longValue && longValue <= Short.MAX_VALUE) {
value = (short) longValue;
} else if (requiredType == Byte.class && Byte.MIN_VALUE <= longValue && longValue <= Byte.MAX_VALUE) {
value = (byte) longValue;
}
}
if (value instanceof Long &&
(requiredType.equals(Integer.class) || requiredType.equals(Short.class) || requiredType.equals(Byte.class))) {
String msg = "Claim '" + name + "' value is too large or too small to be represented as a " +
requiredType.getName() + " instance (would cause numeric overflow).";
throw new RequiredTypeException(msg);
}
if (!requiredType.isInstance(value)) {
throw new RequiredTypeException(String.format(CONVERSION_ERROR_MSG, value.getClass(), requiredType));
}
return requiredType.cast(value);
}
}
View on GitHub (pinned to fb71496164)
Solutions
- Request the claim as its natural deserialized type (e.g. Map.class) and map it to your POJO yourself.
- Register a custom Deserializer via JwtParserBuilder.deserializer() configured to produce your desired types (see jjwt#json-jackson-custom-types).
- Use the Jackson ObjectMapper.convertValue(map, MyPojo.class) on the raw claim value.
- Catch RequiredTypeException and handle the type mismatch explicitly.
Example fix
// before
User user = claims.get("user", User.class); // RequiredTypeException
// after
Map<String, Object> map = claims.get("user", Map.class);
User user = objectMapper.convertValue(map, User.class); Defensive patterns
Strategy: type-guard
Validate before calling
Object v = claims.get(name);
if (v != null && !requiredType.isInstance(v)) { /* convert manually or configure deserializer */ } Type guard
<T> T claimAs(Claims c, String name, Class<T> type) { Object v = c.get(name); return type.isInstance(v) ? type.cast(v) : null; } Try / catch
try { return claims.get(name, MyPojo.class); } catch (RequiredTypeException e) { Map<String,Object> m = claims.get(name, Map.class); return objectMapper.convertValue(m, MyPojo.class); } Prevention
- Configure a custom Deserializer (JwtParserBuilder.deserializer()) for POJO claims
- Know your deserializer's default types (Map/List for nested JSON)
- Convert raw Map/List values explicitly with ObjectMapper.convertValue
When it happens
Trigger: Calling claims.get(name, SomeType.class) where the claim deserialized as a type JJWT does not convert — e.g. a nested JSON object arriving as LinkedHashMap but requested as a custom POJO class.
Common situations: Reading custom claim objects from a token parsed with the default Jackson/Gson deserializer; expecting POJOs that the JSON deserializer never instantiated; type changes after migrating parsers.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Claim '' value is too large or too small to be represented a
- Unexpected Claims JWS.
- Unexpected Claims JWE.
- Unable to deserialize: ${t.getMessage()}
- Cannot create Date from '' value ''. Cause:
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/c9b10ab0eae90752.
Report an issue: GitHub.