{"record":{"id":"fb60c1af7347f3ae","repo":"eclipse-vertx/vert.x","slug":"expected-an-iso-8601-formatted-date-time","errorCode":null,"errorMessage":"Expected an ISO 8601 formatted date time","messagePattern":"Expected an ISO 8601 formatted date time","errorType":"exception","errorClass":"InvalidFormatException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/json/jackson/InstantDeserializer.java","lineNumber":32,"sourceCode":"import com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.databind.DeserializationContext;\nimport com.fasterxml.jackson.databind.JsonDeserializer;\nimport com.fasterxml.jackson.databind.exc.InvalidFormatException;\n\nimport java.io.IOException;\nimport java.time.DateTimeException;\nimport java.time.Instant;\n\nimport static java.time.format.DateTimeFormatter.ISO_INSTANT;\n\nclass InstantDeserializer extends JsonDeserializer<Instant> {\n  @Override\n  public Instant deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {\n    String text = p.getText();\n    try {\n      return Instant.from(ISO_INSTANT.parse(text));\n    } catch (DateTimeException e) {\n      throw new InvalidFormatException(p, \"Expected an ISO 8601 formatted date time\", text, Instant.class);\n    }\n  }\n}\n","sourceCodeStart":14,"sourceCodeEnd":36,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/json/jackson/InstantDeserializer.java#L14-L36","documentation":"InstantDeserializer is the Jackson deserializer Vert.x registers for java.time.Instant. It parses the string with DateTimeFormatter.ISO_INSTANT; if parsing throws DateTimeException, it rethrows as Jackson InvalidFormatException with message 'Expected an ISO 8601 formatted date time', so JSON decoding of a non-ISO-8601 timestamp fails.","triggerScenarios":"Decoding JSON containing an Instant field whose value is not ISO 8601: epoch millis as a number-context string like '1696000000000', formats like '2024-01-01 10:00:00' (space instead of T, missing timezone), or locale-formatted dates.","commonSituations":"Consuming third-party API timestamps (epoch millis, RFC 1123) into Instant fields; database dumps with 'yyyy-MM-dd HH:mm:ss' values; payloads produced by non-Jackson serializers with different date conventions; frontend sending Date.toString().","solutions":["Convert the value to ISO 8601 (e.g. Instant.ofEpochMilli(...).toString() => '2023-09-29T15:06:40Z') before sending/decoding","Change the field type to String or long and convert manually with Instant.ofEpochMilli/ofEpochSecond","Register a custom Instant deserializer that detects epoch-millis or other formats","Normalize producer-side formatting to DateTimeFormatter.ISO_INSTANT output"],"exampleFix":"// before\n{\"createdAt\": 1696000000000} // InvalidFormatException: Expected an ISO 8601 formatted date time\n// after\n{\"createdAt\": \"2023-09-29T15:06:40Z\"}\n// or in Java: instant.toString() when serializing","handlingStrategy":"validation","validationCode":"public static boolean isIsoInstant(String s) {\n  if (s == null) return false;\n  try { Instant.from(ISO_INSTANT.parse(s)); return true; }\n  catch (DateTimeParseException e) { return false; }\n}","typeGuard":"static boolean isInstantShaped(Object v) {\n  return v instanceof String s && s.matches(\"\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}(\\\\.\\\\d+)?(Z|[+-]\\\\d{2}:\\\\d{2})\");\n}","tryCatchPattern":"try {\n  Config cfg = Json.decodeValue(buf, Config.class);\n} catch (DecodeException e) {\n  if (e.getCause() instanceof InvalidFormatException ife && ife.getTargetType() == Instant.class) {\n    // normalize the timestamp then retry\n  }\n}","preventionTips":["Always serialize Instants with Instant.toString() / DateTimeFormatter.ISO_INSTANT","Convert epoch-millis from external APIs with Instant.ofEpochMilli before mapping","Keep Instant fields as String in DTOs when producers use non-ISO formats","Add contract tests asserting timestamp format on API payloads"],"tags":["json","deserialization","date-format","iso-8601","jackson"],"backgroundTag":"invalid-date-format","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}