google/gson · error · JsonSyntaxException

Failed parsing ' ' as Date; at path

Error message

Failed parsing '${s}' as Date; at path ${path}

What it means

DefaultDateTypeAdapter tries every configured DateFormat, then falls back to ISO8601Utils.parse; if all attempts throw ParseException it wraps the final failure in a JsonSyntaxException naming the offending string and JSON path. This is the catch-all 'I could not interpret this token as a Date' error.

Solutions

  1. Set the matching pattern via GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssX").create().
  2. Register a custom TypeAdapter<Date> that parses the exact incoming format.
  3. If the producer can change, emit ISO8601 (e.g. java.time.Instant toString).
  4. Coerce epoch-millis numbers to Date with a custom deserializer rather than relying on string parsing.

Example fix

// before
val gson = GsonBuilder().setDateFormat("yyyy-MM-dd").create()
gson.fromJson("\"2024-01-15T10:30:00Z\"", Date::class.java) // fails

// after: match the actual input format
val gson = GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssX").create()
gson.fromJson("\"2024-01-15T10:30:00Z\"", Date::class.java)
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-parse and validate the date with the configured format
static boolean matchesFormat(String s, String pattern) {
  try { new SimpleDateFormat(pattern, Locale.US).parse(s); return true; }
  catch (ParseException e) { return false; }
}
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssX").create();

Try / catch

try {
  gson.fromJson(json, DateHolder.class);
} catch (JsonSyntaxException e) {
  if (e.getMessage().startsWith("Failed parsing ")) {
    // date format mismatch: adjust setDateFormat or coerce input
    log.warn("Unparseable date: {}", e.getMessage());
  }
  throw e;
}

Prevention

When it happens

Trigger: Deserializing a JSON string into a java.util.Date (or Date subclass) where the string matches neither the GsonBuilder.setDateFormat pattern(s) nor any ISO8601 variant. Example: format set to 'yyyy-MM-dd' but JSON contains '01/15/2024'.

Common situations: Switching GsonBuilder date format after data was produced; locale-sensitive default formats differing between JVMs; consuming an external API whose date format (e.g. epoch millis as number, RFC-1123) Gson doesn't try; mixing SimpleDateFormat instances across threads.

Related errors


AI-assisted analysis of google/gson@310ac341f2 (2026-08-10). Data as JSON: /api/errors/97f4496c51b13ba9. Report an issue: GitHub.

Appendix: source

Thrown at gson/src/main/java/com/google/gson/internal/bind/DefaultDateTypeAdapter.java:184

    String s = in.nextString();
    // Needs to be synchronized since JDK DateFormat classes are not thread-safe
    synchronized (dateFormats) {
      for (DateFormat dateFormat : dateFormats) {
        TimeZone originalTimeZone = dateFormat.getTimeZone();
        try {
          return dateFormat.parse(s);
        } catch (ParseException ignored) {
          // OK: try the next format
        } finally {
          dateFormat.setTimeZone(originalTimeZone);
        }
      }
    }

    try {
      return ISO8601Utils.parse(s, new ParsePosition(0));
    } catch (ParseException e) {
      throw new JsonSyntaxException(
          "Failed parsing '" + s + "' as Date; at path " + in.getPreviousPath(), e);
    }
  }

  @Override
  public String toString() {
    DateFormat defaultFormat = dateFormats.get(0);
    if (defaultFormat instanceof SimpleDateFormat) {
      return SIMPLE_NAME + '(' + ((SimpleDateFormat) defaultFormat).toPattern() + ')';
    } else {
      return SIMPLE_NAME + '(' + defaultFormat.getClass().getSimpleName() + ')';
    }
  }
}

View on GitHub (pinned to 310ac341f2)