apache/flink · error · IllegalStateException

TypeInformation cannot be filled in for the type after it ha

Error message

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.

What it means

Transformation.setOutputType fills in type information after a transformation is created (e.g., via type hints). It refuses to overwrite once the type has already been read (getOutputType was called), tracked by a one-way 'typeUsed' latch, so different parts of the job graph cannot assume different output types.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/dag/Transformation.java:563

     */
    @Nullable
    public String getCoLocationGroupKey() {
        return coLocationGroupKey;
    }

    /**
     * Tries to fill in the type information. Type information can be filled in later when the
     * program uses a type hint. This method checks whether the type information has ever been
     * accessed before and does not allow modifications if the type was accessed already. This
     * ensures consistency by making sure different parts of the operation do not assume different
     * type information.
     *
     * @param outputType The type information to fill in.
     * @throws IllegalStateException Thrown, if the type information has been accessed before.
     */
    public void setOutputType(TypeInformation<T> outputType) {
        if (typeUsed) {
            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(

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Move the type hint (.returns(...)) to be the FIRST call right after the transformation function, before any type-dependent operation.
  2. Remove any intermediate getOutputType()/plan-printing calls that run before the hint is set.
  3. Have your function implement ResultTypeQueryable and return its TypeInformation directly, removing the need for a runtime hint.
  4. Avoid reordering operators between the source transformation and the .returns() call.

Example fix

// before: data.map(fn).keyBy(x -> x).returns(Types.POJO(MyClass.class))  // typeUsed already true -> throws
// after:  data.map(fn).returns(Types.POJO(MyClass.class)).keyBy(x -> x)
Defensive patterns

Strategy: validation

Validate before calling

// Ensure no type access happens before the hint; call returns() immediately after the transformation
DataStream<MyPojo> mapped = source.map(fn).returns(TypeInformation.of(MyPojo.class));
// Only after returns() may you call keyBy/connect/getOutputType/etc.

Try / catch

try {
    transform.setOutputType(t);
} catch (IllegalStateException e) {
    if (e.getMessage().contains("cannot be filled in for the type after it has been used")) {
        log.error("Type hint must be set before any type access; move .returns() right after the transformation");
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling .returns(...) / setOutputType() AFTER getOutputType() (or any internal operation that reads the output type, such as keyBy, connect, or plan printing) has already been invoked on the same transformation.

Common situations: Chaining .returns(TypeInformation.of(...)) after type-dependent operations instead of immediately after the producing transformation; calling execute() or printing the execution plan before setting the type hint; debugging code that touches getOutputType() before the hint.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/74b805ada30efffa. Report an issue: GitHub.