apache/flink · error · IllegalArgumentException
Invalid time unit:
Error message
Invalid time unit:
What it means
Thrown by TimestampColumnReader when decoding a Parquet TIMESTAMP column whose logical-type annotation carries a time unit that does not match MILLIS, MICROS, or NANOS in the reader's switch. Because the switch covers all three legal units, reaching the default branch in practice means the timeUnit object was null or an unexpected/enum-extended value, typically the result of a parquet-mr version mismatch or a malformed logical type annotation in the file.
Source
Thrown at flink-formats/flink-parquet/src/main/java/org/apache/flink/formats/parquet/vector/reader/TimestampColumnReader.java:179
boolean utcTimestamp, long value, LogicalTypeAnnotation.TimeUnit timeUnit) {
final long nanosOfMillisecond;
final long milliseconds;
switch (timeUnit) {
case MILLIS:
milliseconds = value;
nanosOfMillisecond = value % MILLIS_PER_SECOND * NANOS_PER_MILLISECOND;
break;
case MICROS:
milliseconds = value / MICROS_PER_MILLISECOND;
nanosOfMillisecond = (value % MICROS_PER_SECOND) * NANOS_PER_MICROSECONDS;
break;
case NANOS:
milliseconds = value / NANOS_PER_MILLISECOND;
nanosOfMillisecond = value % NANOS_PER_SECOND;
break;
default:
throw new IllegalArgumentException("Invalid time unit: " + timeUnit);
}
if (utcTimestamp) {
return TimestampData.fromEpochMillis(
milliseconds, (int) (nanosOfMillisecond % NANOS_PER_MILLISECOND));
}
Timestamp timestamp = new Timestamp(milliseconds);
timestamp.setNanos((int) nanosOfMillisecond);
return TimestampData.fromTimestamp(timestamp);
}
private static long julianDayToMillis(int julianDay) {
return (julianDay - JULIAN_EPOCH_OFFSET_DAYS) * MILLIS_IN_DAY;
}
}
View on GitHub (pinned to 2f3c205e92)
Solutions
- Verify classpath parquet versions: the job jar must not override the parquet-mr version flink-parquet was built against (check 'mvn dependency:tree' in flink-parquet and compare).
- Inspect the file schema with parquet-tools to confirm the timestamp logical annotation (unit + isAdjustedToUTC) is well-formed.
- If the file uses a non-standard annotation, rewrite it with a standards-compliant writer (Spark/parquet-mr latest) into TIMESTAMP with MILLIS/MICROS/NANOS.
- Report a Flink JIRA with the schema if a valid file triggers it.
Defensive patterns
Strategy: validation
Validate before calling
LogicalTypeAnnotation ann = primitiveType.getLogicalTypeAnnotation();
if (ann instanceof TimestampLogicalTypeAnnotation) {
TimestampLogicalTypeAnnotation ts = (TimestampLogicalTypeAnnotation) ann;
TimeUnit unit = ts.getUnit(); // must be MILLIS, MICROS or NANOS
if (unit == null) throw new IOException("Malformed timestamp annotation in " + path);
} Try / catch
try { ... } catch (IllegalArgumentException e) { /* surface file path and schema */ throw new RuntimeException("Bad timestamp unit in " + path, e); } Prevention
- Never let user jars override the parquet-mr version bundled with flink-parquet.
- Standardize timestamp units (prefer MICROS/MILLIS) in upstream writers.
- Validate schemas of external files with parquet-tools before ingesting.
When it happens
Trigger: Reading a Parquet TIMESTAMP (INT64, isAdjustedToUTC or not) where the LogicalTypeAnnotation.TimeUnit resolved at runtime is not one of the handled enum constants; mixing parquet-mr/parquet-column versions on the classpath so the annotation enum classes differ; a file whose logicalType annotation is missing/malformed so the extracted unit is null.
Common situations: User jars bundling a different parquet-mr version than Flink's flink-parquet; Parquet files produced by writers that emit non-standard timestamp annotations; upgrading Flink while keeping an old shaded parquet in the job jar.
Related errors
- JAR file is not a file: {}
- Missing JobId
- Time unit not recognized
- Unsupported page type: {}
- Failed to read from input stream
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/f0a9ae6d038abbba.
Report an issue: GitHub.