{"record":{"id":"548d5c5c6ec99bae","repo":"eclipse-vertx/vert.x","slug":"expected-an-iso-8601-formatted-date-time-548d5c","errorCode":null,"errorMessage":"Expected an ISO 8601 formatted date time","messagePattern":"Expected an ISO 8601 formatted date time","errorType":"exception","errorClass":"InputCoercionException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java21/io/vertx/core/json/jackson/v3/InstantDeserializer.java","lineNumber":35,"sourceCode":"\nimport java.time.DateTimeException;\nimport java.time.Instant;\n\nimport static java.time.format.DateTimeFormatter.ISO_INSTANT;\n\nclass InstantDeserializer extends StdDeserializer<Instant> {\n\n  InstantDeserializer() {\n    super(Instant.class);\n  }\n\n  @Override\n  public Instant deserialize(JsonParser p, DeserializationContext ctxt) {\n    String text = p.getString();\n    try {\n      return Instant.from(ISO_INSTANT.parse(text));\n    } catch (DateTimeException e) {\n      throw new InputCoercionException(p, \"Expected an ISO 8601 formatted date time\", p.currentToken(), Instant.class);\n    }\n  }\n}\n","sourceCodeStart":17,"sourceCodeEnd":39,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java21/io/vertx/core/json/jackson/v3/InstantDeserializer.java#L17-L39","documentation":"InstantDeserializer parses a JSON string into java.time.Instant and only accepts strings matching the ISO 8601 instant format (e.g. 2024-01-15T10:30:00Z). When the string cannot be parsed by DateTimeFormatter.ISO_INSTANT, it converts the DateTimeException into an InputCoercionException explaining that an ISO 8601 formatted date time was expected. It protects decode targets typed as Instant from silently accepting malformed timestamps.","triggerScenarios":"Decoding JSON into an Instant field or Json.decodeValue target where the JSON string is not strict ISO 8601 instant format: e.g. \"2024-01-15\" (date only), \"2024-01-15T10:30:00\" (no offset), \"2024-01-15 10:30:00Z\" (space separator), epoch millis like \"1705309800000\", or locale-formatted dates.","commonSituations":"Frontend sends a date without the trailing Z or offset; legacy systems send timestamps with a space instead of 'T'; APIs send epoch milliseconds as a string; local date/time values produced by JavaScript toISOString-less formatting.","solutions":["Send timestamps in full ISO 8601 instant format, e.g. \"2024-01-15T10:30:00Z\" or with an explicit offset \"2024-01-15T11:30:00+01:00\"","Normalize the value before decoding: append \"Z\" to date-only strings or convert epoch millis programmatically with Instant.ofEpochMilli","If multiple formats must be supported, decode as String and parse with a custom DateTimeFormatter instead of binding directly to Instant"],"exampleFix":"// before\nString in = \"{\\\"ts\\\":\\\"2024-01-15\\\"}\"; // InputCoercionException\nInstant ts = Json.decodeValue(in, Wrapper.class).getTs();\n// after\nString in = \"{\\\"ts\\\":\\\"2024-01-15T00:00:00Z\\\"}\";\nInstant ts = Json.decodeValue(in, Wrapper.class).getTs();","handlingStrategy":"validation","validationCode":"static boolean isIsoInstant(String s) {\n  try { java.time.Instant.from(java.time.format.DateTimeFormatter.ISO_INSTANT.parse(s)); return true; }\n  catch (java.time.format.DateTimeParseException e) { return false; }\n}","typeGuard":"static java.time.Instant safeParse(String s) {\n  try { return java.time.Instant.parse(s); } catch (Exception e) { return null; }\n}","tryCatchPattern":"try {\n  Instant ts = Json.decodeValue(buf, Wrapper.class).getTs();\n} catch (InputCoercionException | DecodeException e) {\n  log.error(\"timestamp is not ISO 8601: \" + e.getMessage());\n}","preventionTips":["Always emit timestamps with an explicit UTC designator 'Z' or numeric offset","Avoid sending epoch millis or date-only strings where Instant fields are expected","Add schema/format validation at API boundaries before decoding"],"tags":["java","json","date-parsing","iso8601"],"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-14T05:17:10.506Z"}