FasterXML/jackson-databind · error · IllegalArgumentException
Failed to parse Date value '%s': %s
Error message
Failed to parse Date value '%s': %s
What it means
DeserializationContext.parseDate() tries to parse a string into a java.util.Date using the currently configured DateFormat (the mapper's date format or the default ISO-8601 format). When DateFormat.parse() throws a ParseException, Jackson rethrows it as an IllegalArgumentException with both the offending value and the underlying parse message. This is the core failure for date/calendar deserialization when the input doesn't match the expected pattern.
Source
Thrown at src/main/java/tools/jackson/databind/DeserializationContext.java:1185
*/
/**
* Convenience method for parsing a Date from given String, using
* currently configured date format (accessed using
* {@link DeserializationConfig#getDateFormat()}).
*<p>
* Implementation will handle thread-safety issues related to
* date formats such that first time this method is called,
* date format is cloned, and cloned instance will be retained
* for use during this deserialization round.
*/
public Date parseDate(String dateStr) throws IllegalArgumentException
{
try {
DateFormat df = _getDateFormat();
return df.parse(dateStr);
} catch (ParseException e) {
throw new IllegalArgumentException("Failed to parse Date value '%s': %s".formatted(dateStr,
ClassUtil.exceptionMessage(e)));
}
}
/**
* Convenience method for constructing Calendar instance set
* to specified time, to be modified and used by caller.
*/
public Calendar constructCalendar(Date d) {
// 08-Jan-2008, tatu: not optimal, but should work for the most part; let's revise as needed.
Calendar c = Calendar.getInstance(getTimeZone());
c.setTime(d);
return c;
}
/*
/**********************************************************************
/* Extension points for more esoteric data coercionView on GitHub (pinned to a50c7d2a1d)
Solutions
- Set a matching date format on the mapper or field: mapper.setDateFormat(new SimpleDateFormat("MM/dd/yyyy")) or @JsonFormat(shape=STRING, pattern="MM/dd/yyyy").
- Validate/sanitize incoming date strings upstream so only the expected pattern reaches Jackson.
- Enable lenient parsing: ((SimpleDateFormat)fmt).setLenient(true) on the configured format.
- Use a custom ValueDeserializer for Date that tries multiple patterns, or switch the field to java.time.LocalDate/Instant with ACCEPT_CASE_INSENSITIVE_VALUES / custom adapters.
- Enable DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE and verify the input includes/excludes timezone as the pattern expects.
Example fix
// before
ObjectMapper m = new ObjectMapper(); // default ISO format
Date d = m.readValue("\"01/14/2024\"", Date.class); // fails
// after
SimpleDateFormat f = new SimpleDateFormat("MM/dd/yyyy");
f.setTimeZone(TimeZone.getTimeZone("UTC"));
JsonMapper m = JsonMapper.builder().defaultDateFormat(f).build();
Date d = m.readValue("\"01/14/2024\"", Date.class); Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate a date string against the configured format before parse
static boolean isParsable(DateFormat fmt, String s) {
try { synchronized (fmt) { fmt.parse(s); } return true; }
catch (ParseException e) { return false; }
} Type guard
// No compile-time type guard for runtime string parsing; rely on validation.
Try / catch
try {
return mapper.readValue(json, Date.class);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Failed to parse Date value")) {
// fall back: store raw string or use a default date
}
throw e;
} Prevention
- Set an explicit, documented date format on the mapper or field via @JsonFormat.
- Centralize date parsing in one place so the format is consistent across your app.
- Use java.time (LocalDate/Instant) with dedicated deserializers instead of java.util.Date where possible.
- Add integration tests using real production date samples.
When it happens
Trigger: Deserializing a date field whose string value doesn't match the configured date format (e.g. '2024/01/01' against an ISO format, or 'Jan 1st' against 'yyyy-MM-dd'); no custom date format set and the input is non-ISO; locale/timezone mismatch causing the parser to reject a value; a numeric timestamp string where a formatted date was expected (or vice versa).
Common situations: Default Jackson expects ISO-8601 ('yyyy-MM-dd'T'HH:mm:ss.SSSX') but the API/DB returns 'MM/dd/yyyy'; timezone differences between server and client producing unparseable offsets; mixing java.util.Date with java.time types after a partial migration; CSV/legacy feeds with inconsistent date shapes; a JsonFormat annotation with a pattern that doesn't cover all incoming values.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid abstract type resolution from {} to {}: latter is no
- Cannot handle managed/back reference '{}': type: value deser
- AnnotationIntrospector returned Converter definition of type
- AnnotationIntrospector returned Class {}; expected Class<Con
- Only support `JavaType` implementation of `ResolvedType`, no
AI-assisted analysis of FasterXML/jackson-databind@a50c7d2a1d (2026-08-06).
Data as JSON: /api/errors/141426c388a70dfe.
Report an issue: GitHub.