jwtk/jjwt · error · IllegalArgumentException

Cannot create Date from '' value ''. Cause:

Error message

Cannot create Date from '' value ''. Cause: 

What it means

DefaultClaims.get(name, requiredType) converts date-like claim values (issued-at, expiration, etc.) from their stored numeric-seconds or ISO-8601 form into a java.util.Date via JwtDateConverter. If the stored value cannot be interpreted as a date, the converter throws and get() rethrows it as an IllegalArgumentException naming the claim and the underlying cause.

Source

Thrown at impl/src/main/java/io/jsonwebtoken/impl/DefaultClaims.java:122

    public <T> T get(String claimName, Class<T> requiredType) {
        Assert.notNull(requiredType, "requiredType argument cannot be null.");

        Object value = this.idiomaticValues.get(claimName);
        if (requiredType.isInstance(value)) {
            return requiredType.cast(value);
        }

        value = get(claimName);
        if (value == null) {
            return null;
        }

        if (Date.class.equals(requiredType)) {
            try {
                value = JwtDateConverter.toDate(value); // NOT specDate logic
            } catch (Exception e) {
                String msg = "Cannot create Date from '" + claimName + "' value '" + value + "'. Cause: " + e.getMessage();
                throw new IllegalArgumentException(msg, e);
            }
        }

        return castClaimValue(claimName, value, requiredType);
    }

    private <T> T castClaimValue(String name, Object value, Class<T> requiredType) {

        if (value instanceof Long || value instanceof Integer || value instanceof Short || value instanceof Byte) {
            long longValue = ((Number) value).longValue();
            if (Long.class.equals(requiredType)) {
                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;

View on GitHub (pinned to fb71496164)

Solutions

  1. Inspect the token payload (decode the JWT) to see the actual value of the named date claim and fix the issuer so it writes numeric epoch seconds or valid ISO-8601.
  2. Parse the value yourself: read the raw claim via claims.get(name) and convert manually instead of requesting Date.class.
  3. Wrap the get* call in try-catch for IllegalArgumentException and treat the token as invalid/untrusted.
  4. If you control deserialization, register a custom JSON Deserializer via JwtParserBuilder.deserializer() that produces Date-compatible values.

Example fix

// before
Date exp = claims.getExpiration(); // throws
// after
Object raw = claims.get("exp");
Date exp = raw instanceof Number
    ? new Date(((Number) raw).longValue() * 1000L)
    : null;
Defensive patterns

Strategy: validation

Validate before calling

Object v = claims.get("exp");
if (!(v instanceof Number) && !(v instanceof String)) throw new IllegalArgumentException("exp is not a date-like value: " + v);

Type guard

boolean isDateLike(Object v) { return v instanceof Number || (v instanceof String s && !s.isBlank()); }

Try / catch

try { Date exp = claims.getExpiration(); } catch (IllegalArgumentException e) { /* treat token as invalid */ }

Prevention

When it happens

Trigger: Calling jwt.getBody().getExpiration()/getIssuedAt()/getNotBefore() (or get(name, Date.class)) when the corresponding claim in the JWT payload is not a valid date value — e.g. a string that is not ISO-8601, an unexpected object/array, or a non-numeric epoch value.

Common situations: Tokens minted by another library that serializes exp/iat/nbf as strings or nested objects; a corrupted or hand-edited token; a custom serializer writing claims in an unexpected format.

Related errors


AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09). Data as JSON: /api/errors/e2a3c36c818573bf. Report an issue: GitHub.