jwtk/jjwt · error · IllegalArgumentException
Cannot create Date from object of type ${v.getClass().getNam
Error message
Cannot create Date from object of type ${v.getClass().getName()}. What it means
JwtDateConverter.toDate converts a JWT date claim value (exp, nbf, iat) into a java.util.Date. It accepts Number (epoch seconds/millis) and ISO-8601 String inputs; any other type throws IllegalArgumentException 'Cannot create Date from object of type ...'.
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/lang/JwtDateConverter.java:91
* @param v the object value to represent as a Date.
* @return a {@link Date} equivalent of the specified object value using heuristics.
*/
public static Date toDate(Object v) {
if (v == null) {
return null;
} else if (v instanceof Date) {
return (Date) v;
} else if (v instanceof Calendar) { //since 0.10.0
return ((Calendar) v).getTime();
} else if (v instanceof Number) {
//assume millis:
long millis = ((Number) v).longValue();
return new Date(millis);
} else if (v instanceof String) {
return parseIso8601Date((String) v); //ISO-8601 parsing since 0.10.0
} else {
String msg = "Cannot create Date from object of type " + v.getClass().getName() + ".";
throw new IllegalArgumentException(msg);
}
}
/**
* Parses the specified ISO-8601-formatted string and returns the corresponding {@link Date} instance.
*
* @param value an ISO-8601-formatted string.
* @return a {@link Date} instance reflecting the specified ISO-8601-formatted string.
* @since 0.10.0
*/
private static Date parseIso8601Date(String value) throws IllegalArgumentException {
try {
return DateFormats.parseIso8601Date(value);
} catch (ParseException e) {
String msg = "String value is not a JWT NumericDate, nor is it ISO-8601-formatted. " +
"All heuristics exhausted. Cause: " + e.getMessage();
throw new IllegalArgumentException(msg, e);
}View on GitHub (pinned to fb71496164)
Solutions
- Pass epoch-millis Number (new Date().getTime()) or an ISO-8601 String for date claims.
- Inspect the raw JSON of the token to see the claim's actual type and fix the producer.
- Pre-validate with instanceof Number/String before passing to the converter, converting or rejecting other types.
Example fix
// before
jwt.claim("exp", someCustomDateObject); // unsupported type
// after
jwt.claim("exp", System.currentTimeMillis() / 1000L); // epoch seconds as Number Defensive patterns
Strategy: type-guard
Validate before calling
if (!(v instanceof Number) && !(v instanceof String)) {
throw new IllegalArgumentException("Date claim must be epoch number or ISO-8601 string: " + v);
} Type guard
static Date toDate(Object v) {
if (v instanceof Number) return new Date(((Number) v).longValue());
if (v instanceof String) return Date.from(Instant.parse((String) v));
return null;
} Try / catch
try {
Date d = (Date) claims.get("exp");
} catch (IllegalArgumentException | ClassCastException e) {
// parse claim manually or reject the token
} Prevention
- Always write date claims as epoch seconds/millis Numbers or ISO-8601 Strings
- Validate third-party tokens' date claim types before processing
- Use io.jsonwebtoken's Claims date getters (getExpiration) which handle conversion for you
When it happens
Trigger: A date claim deserialized as something other than Number or String - e.g. a Map/List from malformed JSON, a Boolean, or a custom object set programmatically into a claim typed as a date.
Common situations: Custom JSON deserializers producing non-standard types; manually building claims with wrong types (new Object()); third-party token issuers emitting dates in exotic formats parsed into containers.
Related errors
- Cannot cast ${value.getClass().getName()} to ${COLLECTION_TY
- Cannot cast ${value.getClass().getName()} to ${IDIOMATIC_TYP
- ${message}Object of class [${objClassName}] must be an insta
- ${message}${subType} is not assignable to ${superType}
- Source is not an array:
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/09c4864b60303770.
Report an issue: GitHub.