apache/flink · error · JsonParseException
Fail to deserialize at field: %s.
Error message
Fail to deserialize at field: %s.
What it means
Thrown by the ROW converter in JsonToRowDataConverters when any per-field converter throws while converting one field of a JSON object. It is a wrapper: the message names the field, and the cause carries the real conversion failure (type mismatch, bad numeric/date literal, variant/bytes failure, etc.). Fixing it means fixing the nested cause for the named field.
Source
Thrown at flink-formats/flink-json/src/main/java/org/apache/flink/formats/json/JsonToRowDataConverters.java:365
final JsonToRowDataConverter[] fieldConverters =
rowType.getFields().stream()
.map(RowType.RowField::getType)
.map(this::createConverter)
.toArray(JsonToRowDataConverter[]::new);
final String[] fieldNames = rowType.getFieldNames().toArray(new String[0]);
return jsonNode -> {
ObjectNode node = (ObjectNode) jsonNode;
int arity = fieldNames.length;
GenericRowData row = new GenericRowData(arity);
for (int i = 0; i < arity; i++) {
String fieldName = fieldNames[i];
JsonNode field = node.get(fieldName);
try {
Object convertedField = convertField(fieldConverters[i], fieldName, field);
row.setField(i, convertedField);
} catch (Throwable t) {
throw new JsonParseException(
String.format("Fail to deserialize at field: %s.", fieldName), t);
}
}
return row;
};
}
private Object convertField(
JsonToRowDataConverter fieldConverter, String fieldName, JsonNode field) {
if (field == null) {
if (failOnMissingField) {
throw new JsonParseException("Could not find field with name '" + fieldName + "'.");
} else {
return null;
}
} else {
return fieldConverter.convert(field);
}View on GitHub (pinned to 2f3c205e92)
Solutions
- Read the cause chain of the JsonParseException to identify the underlying failure for the named field
- Check the field's JSON value in the failing record against the declared Flink type and correct the DDL or the data
- For date/time fields, verify the value matches the ISO-8601 formats Flink expects (or configure a custom format if supported by the pipeline)
- If bad records are expected and skippable, set the format's ignore-parse-errors option where available (Canal/Debezium variants) or filter/quarantine upstream
Example fix
// before: JSON {"ts": "2024-13-45 99:00:00"} against TIMESTAMP(3)
// after: fix upstream to emit "2024-01-05 10:00:00" or declare the column STRING and parse leniently in a UDF Defensive patterns
Strategy: try-catch
Try / catch
catch (JsonParseException e) — read getFieldName from message and unwrap getCause(); fix the inner conversion (type mismatch / format) rather than retrying the same record.
Prevention
- Contract-test the declared ROW schema against representative records
- Watch for schema drift alerts from upstream
- Use ignore-parse-errors only with monitoring of skipped counts
When it happens
Trigger: Any field-level conversion error inside a ROW: a JSON string where a number is expected, an invalid TIMESTAMP/DATE format, a failed VARIANT or BINARY conversion (see 1400/1401), a DECIMAL with more digits than precision, etc. The wrapped converters run per record, so this appears at runtime on the offending message.
Common situations: Upstream schema drift (a field flips from number to string); malformed date/timestamp strings; nulls represented as "" instead of JSON null; precision/scale mismatches on DECIMAL columns.
Related errors
- Fail to serialize at field: %s.
- Fail to deserialize at field: %s.
- Illegal JSON object data...
- Illegal Json Data...
- Could not find field with name '%s'.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/35f29d4f8beea657.
Report an issue: GitHub.