apache/flink · error · InvalidTypesException
The return type of function '{functionName}' could not be de
Error message
The return type of function '{functionName}' could not be determined automatically, due to type erasure. You can give type information hints by using the returns(...) method on the result of the transformation call, or by letting your function implement the 'ResultTypeQueryable' interface. What it means
When Flink cannot infer a transformation's return type (typically due to generic type erasure), it stores a MissingTypeInfo placeholder. On the first getOutputType() call it throws InvalidTypesException telling the user the type could not be determined and to supply a hint, surfacing the problem at job-construction time rather than at runtime.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/dag/Transformation.java:581
throw new IllegalStateException(
"TypeInformation cannot be filled in for the type after it has been used. "
+ "Please make sure that the type info hints are the first call after"
+ " the transformation function, "
+ "before any access to types or semantic properties, etc.");
}
this.outputType = outputType;
}
/**
* Returns the output type of this {@code Transformation} as a {@link TypeInformation}. Once
* this is used once the output type cannot be changed anymore using {@link #setOutputType}.
*
* @return The output type of this {@code Transformation}
*/
public TypeInformation<T> getOutputType() {
if (outputType instanceof MissingTypeInfo) {
MissingTypeInfo typeInfo = (MissingTypeInfo) this.outputType;
throw new InvalidTypesException(
"The return type of function '"
+ typeInfo.getFunctionName()
+ "' could not be determined automatically, due to type erasure. "
+ "You can give type information hints by using the returns(...) "
+ "method on the result of the transformation call, or by letting "
+ "your function implement the 'ResultTypeQueryable' "
+ "interface.",
typeInfo.getTypeException());
}
typeUsed = true;
return this.outputType;
}
/**
* Set the buffer timeout of this {@code Transformation}. The timeout defines how long data may
* linger in a partially full buffer before being sent over the network.
*
* <p>Lower timeouts lead to lower tail latencies, but may affect throughput. For Flink 1.5+,View on GitHub (pinned to 2f3c205e92)
Solutions
- Add .returns(TypeInformation.of(...)) as the first call after the transformation function.
- Implement ResultTypeQueryable on your function and return the TypeInformation explicitly.
- Replace the lambda with a named class so Flink can introspect the generic method signature.
- Use Types.POJO(...) / Types.TUPLE(...) hints to make the return type concrete.
Example fix
// before: data.map(x -> new MyResult(...)) // type erased -> MissingTypeInfo -> throws on getOutputType // after: data.map(x -> new MyResult(...)).returns(TypeInformation.of(MyResult.class))
Defensive patterns
Strategy: try-catch
Try / catch
try {
TypeInformation<T> out = transform.getOutputType();
} catch (InvalidTypesException e) {
if (e.getMessage().contains("could not be determined automatically")) {
// Add .returns(...) after the transformation or implement ResultTypeQueryable
log.error("Return type erased; supply a type hint or implement ResultTypeQueryable");
}
throw e;
} Prevention
- Add .returns(TypeInformation.of(...)) right after any transformation returning a generic type.
- Implement ResultTypeQueryable on functions returning generics to make the type explicit.
- Use named classes instead of lambdas so Flink can read the generic signature.
- Run the job graph construction in a unit test to surface type-erasure failures early.
When it happens
Trigger: Calling getOutputType() (or any operation needing the output type) on a transformation whose function returns a generic type Flink could not resolve — e.g., a lambda or anonymous MapFunction returning List<X> or a parameterized POJO whose type argument is erased.
Common situations: Lambdas or anonymous functions returning generic collections/POJOs where the type parameter is erased; Tuple returns without explicit TupleTypeInfo; nested generics; using .map(x -> new Result(...)) for a non-final Result class whose generic signature is invisible.
Related errors
- TypeInformation cannot be filled in for the type after it ha
- The implementation of AbstractDeserializationSchema is using
- Could not create the type information for '{}'. The most com
- Could not create the type information for '{}'. The most com
- The TypeHint is using a generic variable.This is not support
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/5b6b028937c4d81b.
Report an issue: GitHub.