apache/flink · error · IllegalArgumentException
Csv does not support TIME type with precision: %s, it only s
Error message
Csv does not support TIME type with precision: %s, it only supports precision 0 ~ 3.
What it means
CsvToRowDataConverters.convertToTime refuses TIME(p) columns with precision > 3: CSV parsing goes through LocalTime.parse and keeps only milliseconds (see FLINK-17525), so higher precisions would silently lose digits. The converter therefore fails fast with IllegalArgumentException while building the deserialization schema rather than corrupting data at runtime.
Source
Thrown at flink-formats/flink-csv/src/main/java/org/apache/flink/formats/csv/CsvToRowDataConverters.java:244
// avoid redundant toString and parseDouble, for better performance
return (float) jsonNode.asDouble();
} else {
return Float.parseFloat(jsonNode.asText().trim());
}
}
private int convertToDate(JsonNode jsonNode) {
// csv currently is using Date.valueOf() to parse date string
return (int) Date.valueOf(jsonNode.asText()).toLocalDate().toEpochDay();
}
private CsvToRowDataConverter convertToTime(TimeType timeType) {
final int precision = timeType.getPrecision();
// csv currently is using Time.valueOf() to parse time string
// TODO: FLINK-17525 support millisecond and nanosecond
// get number of milliseconds of the day
if (precision > 3) {
throw new IllegalArgumentException(
"Csv does not support TIME type "
+ "with precision: "
+ precision
+ ", it only supports precision 0 ~ 3.");
}
return jsonNode -> {
LocalTime localTime = LocalTime.parse(jsonNode.asText());
int mills = (int) (localTime.toNanoOfDay() / 1000_000L);
// this is for rounding off values out of precision
if (precision == 2) {
mills = mills / 10 * 10;
} else if (precision == 1) {
mills = mills / 100 * 100;
} else if (precision == 0) {
mills = mills / 1000 * 1000;
}
return mills;
};View on GitHub (pinned to 2f3c205e92)
Solutions
- Change the column to TIME(3) or plain TIME (precision 0) if millisecond resolution is acceptable.
- Ingest the field as STRING and parse to a higher-precision type downstream (e.g. TO_TIMESTAMP_LSB or custom UDF).
- If micro/nano precision is a hard requirement, vote/track FLINK-17525 or use a format that supports it (avro/json with LONG micros).
Example fix
-- before event_time TIME(6), -- after event_time TIME(3), -- or: event_time STRING parsed downstream
Defensive patterns
Strategy: validation
Validate before calling
// Check every TIME column when format='csv':
for (Column c : table.getResolvedSchema().getColumns()) {
if (c.getDataType().getLogicalType() instanceof TimeType
&& ((TimeType) c.getDataType().getLogicalType()).getPrecision() > 3) {
throw new ValidationException("csv does not support TIME(>3): " + c.getName());
}
} Type guard
static boolean csvTimePrecisionOk(TimeType t) { return t.getPrecision() <= 3; } Prevention
- Default to TIME(3) or plain TIME in csv DDLs
- Ingest high-precision times as STRING and parse downstream
- Track FLINK-17525 for micro/nano TIME support
When it happens
Trigger: A csv-format table declaring TIME(4) through TIME(9); common when copying a TIME(6) column definition from another system (e.g. Oracle/MySQL TIME(6), or a JSON/Avro schema with micro precision).
Common situations: Porting DDLs from databases whose default TIME precision exceeds 3; upstream producers emitting microseconds in time fields; schema-import tooling that preserves source precision verbatim.
Related errors
- Avro does not support TIME type with precision: %s, it only
- Format cannot define a quote character and disabled quote ch
- Unsupported type information '%s' for field '%s'.
- Unsupported type '%s' for field '%s'.
- Only simple types are supported in the second level nesting
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/1699a26728e022d9.
Report an issue: GitHub.