apache/flink · error · InvalidTypesException
SQL time type expected.
Error message
SQL time type expected.
What it means
Thrown during input type validation when the TypeInformation is a SqlTimeTypeInfo (java.sql.Date, java.sql.Time, java.sql.Timestamp) but the reflected Type is not a recognized SQL time type. `SqlTimeTypeInfo.getInfoFor()` returns null for the class, indicating it is not one of the three supported SQL temporal types.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractor.java:1521
if (!(type instanceof Class<?>)
|| (actual = BasicTypeInfo.getInfoFor((Class<?>) type)) == null) {
throw new InvalidTypesException("Basic type expected.");
}
// check if correct basic type
if (!typeInfo.equals(actual)) {
throw new InvalidTypesException(
"Basic type '" + typeInfo + "' expected but was '" + actual + "'.");
}
}
// check for Java SQL time types
else if (typeInfo instanceof SqlTimeTypeInfo) {
TypeInformation<?> actual;
// check if SQL time type at all
if (!(type instanceof Class<?>)
|| (actual = SqlTimeTypeInfo.getInfoFor((Class<?>) type)) == null) {
throw new InvalidTypesException("SQL time type expected.");
}
// check if correct SQL time type
if (!typeInfo.equals(actual)) {
throw new InvalidTypesException(
"SQL time type '" + typeInfo + "' expected but was '" + actual + "'.");
}
}
// check for Java Tuples
else if (typeInfo instanceof TupleTypeInfo) {
// check if tuple at all
if (!(isClassType(type) && Tuple.class.isAssignableFrom(typeToClass(type)))) {
throw new InvalidTypesException("Tuple type expected.");
}
// do not allow usage of Tuple as type
if (isClassType(type) && typeToClass(type).equals(Tuple.class)) {
throw new InvalidTypesException("Concrete subclass of Tuple expected.");View on GitHub (pinned to 2f3c205e92)
Solutions
- Ensure the function uses the correct java.sql temporal type (Date, Time, or Timestamp)
- Convert java.time types to java.sql equivalents before the function: `java.sql.Timestamp.from(instant)`
- If using java.time types, do not register SqlTimeTypeInfo — use a POJO or explicit TypeInformation instead
Example fix
// before — java.time vs java.sql mismatch
DataStream<java.time.Instant> stream = ...;
stream.map(new MapFunction<java.sql.Timestamp, X>() { ... });
// after — convert or align
stream.map(instant -> java.sql.Timestamp.from(instant))
.map(new MapFunction<java.sql.Timestamp, X>() { ... }); Defensive patterns
Strategy: validation
Validate before calling
// Check if the reflected type is a valid SQL time type
Class<?> inputClass = myFunctionInputClass; // obtained via reflection
TypeInformation<?> sqlTimeInfo = SqlTimeTypeInfo.getInfoFor(inputClass);
if (sqlTimeInfo == null) {
throw new IllegalArgumentException(
"Type " + inputClass.getName()
+ " is not a recognized SQL time type. "
+ "Use java.sql.Date, java.sql.Time, or java.sql.Timestamp.");
} Prevention
- Use java.sql.Date, java.sql.Time, or java.sql.Timestamp consistently for temporal types
- Convert java.time types to java.sql equivalents at the boundary
- Avoid mixing java.util.Date with java.sql temporal types in the same pipeline
- Standardize on one temporal type framework throughout the pipeline
When it happens
Trigger: A function or stream uses SqlTimeTypeInfo but the actual reflected type from the function signature is not java.sql.Date, java.sql.Time, or java.sql.Timestamp. For example, the function declares a Timestamp input but the stream carries java.util.Date or java.time.Instant.
Common situations: Mixing java.time (Instant, LocalDateTime) with java.sql types in a pipeline. Using java.util.Date where java.sql.Timestamp is expected. Connecting a connector that emits java.sql types to a function expecting java.time types.
Related errors
- SQL time type '{}' expected but was '{}'.
- Basic type expected.
- Basic type '{}' expected but was '{}'.
- Tuple type expected.
- Concrete subclass of Tuple expected.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/e5295b4b02355f06.
Report an issue: GitHub.