google/gson · error · JsonSyntaxException
Failed parsing '" + s + "' as SQL Date; at path " + in.getPr
Error message
Failed parsing '" + s + "' as SQL Date; at path " + in.getPreviousPath()
What it means
SqlDateTypeAdapter parses the JSON string with SimpleDateFormat("MMM d, yyyy") (e.g. 'Jan 1, 2024'). A ParseException is wrapped as JsonSyntaxException. The format is locale and timezone sensitive and is synchronized on the adapter.
Source
Thrown at gson/src/main/java/com/google/gson/internal/sql/SqlDateTypeAdapter.java:69
private final DateFormat format = new SimpleDateFormat("MMM d, yyyy");
private SqlDateTypeAdapter() {}
@Override
public java.sql.Date read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
String s = in.nextString();
synchronized (this) {
TimeZone originalTimeZone = format.getTimeZone(); // Save the original time zone
try {
Date utilDate = format.parse(s);
return new java.sql.Date(utilDate.getTime());
} catch (ParseException e) {
throw new JsonSyntaxException(
"Failed parsing '" + s + "' as SQL Date; at path " + in.getPreviousPath(), e);
} finally {
format.setTimeZone(originalTimeZone); // Restore the original time zone after parsing
}
}
}
@Override
public void write(JsonWriter out, java.sql.Date value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
String dateString;
synchronized (this) {
dateString = format.format(value);
}
out.value(dateString);View on GitHub (pinned to 8b8628c656)
Solutions
- Provide the date string in 'MMM d, yyyy' form, matching the default adapter.
- Register a custom TypeAdapter<java.sql.Date> using the format your producer emits (e.g. 'yyyy-MM-dd') and the desired Locale/TimeZone.
- Deserialize as java.util.Date or java.time.LocalDate instead and convert, if the SQL type is not essential.
Example fix
// before
java.sql.Date d = gson.fromJson("\"2024-01-01\"", java.sql.Date.class);
// after
Gson gson = new GsonBuilder().registerTypeAdapter(java.sql.Date.class, new TypeAdapter<java.sql.Date>() {
private final java.text.DateFormat f = new java.text.SimpleDateFormat("yyyy-MM-dd");
@Override public java.sql.Date read(JsonReader in) throws IOException { return java.sql.Date.valueOf(in.nextString()); }
@Override public void write(JsonWriter out, java.sql.Date v) throws IOException { out.value(v.toString()); }
}).create(); Defensive patterns
Strategy: validation
Validate before calling
boolean isSqlDateParsable(String s) {
if (s == null) return false;
try { java.text.DateFormat f = new java.text.SimpleDateFormat("MMM d, yyyy", Locale.ENGLISH); f.parse(s); return true; }
catch (java.text.ParseException e) { return false; }
} Type guard
static boolean matchesDefaultSqlDateFormat(String s) {
return s != null && s.matches("[A-Z][a-z]{2} \\d{1,2}, \\d{4}");
} Try / catch
try {
java.sql.Date d = gson.fromJson(json, java.sql.Date.class);
} catch (JsonSyntaxException e) {
// parse with a custom format adapter instead
} Prevention
- Register a java.sql.Date adapter matching your producer format (and Locale).
- Pin Locale.ENGLISH for the adapter to avoid host-locale surprises.
- Prefer java.time.LocalDate for new code.
When it happens
Trigger: Deserializing a JSON value into a java.sql.Date field where the string is not in the expected 'MMM d, yyyy' format (e.g. '2024-01-01', ISO format, or a locale-incompatible month abbreviation).
Common situations: Producer emits ISO-8601 or 'yyyy-MM-dd' but Gson's sql.Date adapter expects the long month form; running under a non-English locale where 'Jan' is not a valid month; or mismatched date conventions between layers.
Related errors
- Failed parsing '" + s + "' as SQL Time; at path " + in.getPr
- duplicate key: {key}
- Expecting number, got: " + jsonToken + "; at path " + in.get
- Unexpected token: " + peeked
- Failed parsing '" + s + "' as BigDecimal; at path " + in.get
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/6f4ff1629ab21a3b.json.
Report an issue: GitHub.