apache/flink · error · org.apache.flink.formats.json.JsonParseException
Fail to deserialize at field: %s.
Error message
Fail to deserialize at field: %s.
What it means
JsonParseException thrown per-field by createRowConverter when a named field's conversion throws any Throwable. Note the cause is deliberately not attached — only the field name is reported — so you must reproduce/inspect the payload to learn the underlying reason (type mismatch, number format, etc.). It fires before ignoreParseErrors is consulted at the outer layer, which then either wraps it as 'Failed to deserialize JSON' or skips the row.
Source
Thrown at flink-formats/flink-json/src/main/java/org/apache/flink/formats/json/JsonParserToRowDataConverters.java:426
}
int arity = nameIdxMap.size();
GenericRowData row = new GenericRowData(arity);
int cnt = 0;
jp.nextToken();
while (jp.currentToken() != JsonToken.END_OBJECT) {
if (cnt >= arity) {
skipToNextField(jp);
continue;
}
String fieldName = jp.getText();
jp.nextToken();
Integer idx = nameIdxMap.get(fieldName);
if (idx != null) {
try {
Object convertField = fieldConverters[idx].convert(jp);
row.setField(idx, convertField);
} catch (Throwable t) {
throw new JsonParseException(
String.format("Fail to deserialize at field: %s.", fieldName));
}
jp.nextToken();
cnt++;
} else {
skipToNextField(jp);
}
}
if (cnt < arity && failOnMissingField) {
throw new JsonParseException("Some field is missing in the JSON data.");
}
return row;
};
}
public static void skipToNextField(JsonParser jp) throws IOException {
switch (jp.currentToken()) {
case START_OBJECT:View on GitHub (pinned to 2f3c205e92)
Solutions
- Look at the field named in the message and the raw record from the outer 'Failed to deserialize JSON' wrapper (or DEBUG logs with ignore-parse-errors) to identify the value
- Adjust that column's DDL type or the 'timestamp-format' option to match reality
- Fix the producer data; or set 'json.ignore-parse-errors'='true' to skip bad rows
Example fix
-- before: data contains "amount": "1,024.50" amount DECIMAL(10,2) -- after: normalize at producer, or ingest as string and clean downstream amount STRING
Defensive patterns
Strategy: try-catch
Try / catch
catch (IOException wrapped) { // outer 'Failed to deserialize JSON'
Throwable cause = wrapped.getCause(); // JsonParseException 'Fail to deserialize at field: X'
String field = extractFieldName(cause.getMessage());
deadLetter(record, field);
} Prevention
- Note the field error swallows its cause; keep the raw record for reproduction
- Contract-test field types between producer and DDL in CI
- Choose the right 'timestamp-format' up front to avoid timestamp field failures
When it happens
Trigger: A field's JSON value cannot convert to its declared type: string 'abc' into INT, out-of-range numbers, wrong nested shape (errors 1371-1375 surface here as field failures when nested inside a row).
Common situations: Schema drift (producer adds/changes field types); locale-dependent number formats in strings; nulls in non-nullable positions handled by a later layer; timestamps in an unexpected format vs the configured timestamp-format.
Related errors
- Failed to deserialize JSON '%s'.
- Illegal JSON array data...
- Illegal JSON map data...
- Illegal JSON object data...
- Illegal Json Data...
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/ee388f70ba0a481b.
Report an issue: GitHub.