๐ด The Error You're Seeing
Confirm this matches your console output. If it does, you're in the right place.
2026-02-20 09:15:22.410 WARN 8842 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `java.time.LocalDate`, problem: Cannot parse '2026-01-15 10:00:00']โก Quick Fix Works 80% of the time
Add @JsonFormat(pattern = "yyyy-MM-dd") to your LocalDate field.
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate dateOfBirth;๐ง Why this Happens
Tap to expand the deep technical explanation
The client sent a JSON payload containing a date string. Spring Boot's Jackson library tried to convert this string into a `java.time.LocalDate` object. However, the string format did not match Jackson's default ISO format (yyyy-MM-dd), so the parsing failed.
The HITEC City Parking Spot Analogy:
It's like a customs officer checking a passport. The officer expects the date format to be DD/MM/YYYY, but the passport has MM/DD/YYYY. The officer cannot process the entry because the format doesn't match the expected standard.
๐ How to Reproduce Confirm this is your error
Create a DTO with a `LocalDate` field. Send a POST request with JSON containing `"dateOfBirth": "2026/01/15"` (using slashes instead of dashes). Spring will reject it.
๐ ๏ธ Solutions (5 Ways to Fix)
Add @JsonFormat annotation
๐ Use this when you want to accept a specific date format.
Tell Jackson exactly how to parse the string into a LocalDate.
import com.fasterxml.jackson.annotation.JsonFormat;
public class UserRequest {
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate dateOfBirth;
}Configure global Jackson date format
๐ Use this if all your APIs use the same non-standard date format.
Set the format globally in application.properties so you don't need @JsonFormat on every field.
# application.properties
spring.jackson.date-format=yyyy-MM-dd
# Or for custom patterns:
spring.jackson.dateFormat=yyyy-MM-ddSend the correct ISO format from the client
๐ Use this if you want to stick to defaults.
Ensure your frontend sends dates in the standard ISO-8601 format (YYYY-MM-DD).
// Frontend (JavaScript)
const dateStr = new Date().toISOString().split('T')[0]; // "2026-01-15"
// Send { "dateOfBirth": dateStr }Use a custom Deserializer
๐ Use this if you accept multiple date formats from different clients.
Write a custom class that extends JsonDeserializer and tries parsing multiple formats.
public class MultiDateDeserializer extends JsonDeserializer<LocalDate> {
@Override
public LocalDate deserialize(JsonParser p, DeserializationContext ctxt) {
// Try parsing 'yyyy-MM-dd' and 'dd/MM/yyyy'
}
}
// On DTO:
@JsonDeserialize(using = MultiDateDeserializer.class)
private LocalDate dateOfBirth;Handle the exception globally
๐ Use this to return a clean 400 Bad Request instead of a 500 error.
Catch HttpMessageNotReadableException in a @RestControllerAdvice to format the error nicely.
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<String> handleJsonParse(HttpMessageNotReadableException ex) {
return ResponseEntity.badRequest().body("Invalid JSON format");
}
}๐ Version Notes
Uses jackson-datatype-jsr310 for Java 8 time.
Java 8 time is supported natively, but format matching is stricter.
๐ก๏ธ How to Prevent This Next Time
Always document the expected date format in your API docs. Use `@JsonFormat` explicitly on date fields to remove ambiguity.