google/gson · error · JsonSyntaxException

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

Error message

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

What it means

DefaultDateTypeAdapter.deserializeToDate throws this JsonSyntaxException after every configured DateFormat AND the ISO8601 fallback parser all failed to parse the string {s}. The {path} is the JsonReader's previous path locating the offending field. This is the terminal failure for date deserialization: Gson has exhausted the date pattern(s) registered on the adapter plus the built-in ISO-8601 attempt.

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 8b8628c656)

Solutions

  1. Register a date format matching the producer: new GsonBuilder().setDateFormat("MMM d, yyyy").create().
  2. If multiple formats are possible, register a custom TypeAdapter<Date> that tries each pattern then falls back to ISO-8601 / epoch millis.
  3. If the value is an epoch number, write a small adapter that reads nextLong and constructs new Date(long).
  4. Inspect the {path} and {s} in the exception to identify the exact field and format, then align producer/consumer.

Example fix

// before
Gson gson = new Gson(); // default DEFAULT style
gson.fromJson("{\"d\":\"2025-01-05\"}", Event.class); // JsonSyntaxException

// after
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
gson.fromJson("{\"d\":\"2025-01-05\"}", Event.class);
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify a date string parses with your configured format before deserializing
String s = "2025-01-05";
try { new SimpleDateFormat("yyyy-MM-dd").parse(s); }
catch (ParseException e) { throw new IllegalArgumentException("Bad date: " + s); }

Try / catch

try {
  return gson.fromJson(json, Event.class);
} catch (JsonSyntaxException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Failed parsing '")) {
    throw new InvalidPayloadException("Unparseable date in payload; expected format yyyy-MM-dd", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Deserializing a Date (or Date subclass) where the JSON string does not match any format given to GsonBuilder.setDateFormat(...), the default DEFAULT-style format, the system locale format, the pre-Java-9 US format, or ISO-8601. Example: setDateFormat("yyyy-MM-dd") but input is 'Jan 5, 2025'.

Common situations: Backend sends dates in an unexpected format; locale differences (server en_US vs client de_DE); timestamp vs string mismatch; mixing epoch millis with formatted dates; new API version changed the date format.

Related errors


AI-assisted analysis of google/gson@8b8628c656 (2026-08-04). Data as JSON: /data/errors/36eee2a46255fd9b.json. Report an issue: GitHub.