apache/flink · error · RuntimeException

The Nothing type cannot have a serializer.

Error message

The Nothing type cannot have a serializer.

What it means

NothingTypeInfo is the TypeInformation for the Nothing placeholder type, which represents an unreachable/empty type (e.g., a source that emits no elements, or a dead branch). Because Nothing has no instances, it has no serializer; createSerializer always throws RuntimeException. This is a sentinel: serializing Nothing is a programming error.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/common/typeinfo/NothingTypeInfo.java:72

        return 1;
    }

    @Override
    @PublicEvolving
    public Class<Nothing> getTypeClass() {
        return Nothing.class;
    }

    @Override
    @PublicEvolving
    public boolean isKeyType() {
        return false;
    }

    @Override
    @PublicEvolving
    public TypeSerializer<Nothing> createSerializer(SerializerConfig serializerConfig) {
        throw new RuntimeException("The Nothing type cannot have a serializer.");
    }

    @Override
    public String toString() {
        return getClass().getSimpleName();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof NothingTypeInfo) {
            NothingTypeInfo nothingTypeInfo = (NothingTypeInfo) obj;

            return nothingTypeInfo.canEqual(this);
        } else {
            return false;
        }
    }

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Replace the Nothing-typed source/operator with one that emits a concrete type (e.g., define the source's returned TypeInformation explicitly).
  2. Audit the pipeline for branches where TypeExtractor could not infer a type and defaulted to Nothing; supply an explicit TypeInformation/Returns hint on the source.
  3. Never call createSerializer on a type you have not confirmed is real; guard with a check that typeInfo != NothingTypeInfo before requesting a serializer.

Example fix

// before
DataStream<Nothing> src = env.fromSource(noTypeSource, watermark, "s");
src.getTransformation().getOutputType().createSerializer(cfg); // throws

// after
DataStream<Event> src = env.fromSource(
    typedSource, watermark, "s", TypeInformation.of(Event.class));
Defensive patterns

Strategy: validation

Validate before calling

TypeInformation<?> ti = source.getProducedType();
if (ti instanceof NothingTypeInfo) {
    throw new IllegalStateException(
        "Source type is Nothing; supply a concrete TypeInformation");
}

Type guard

static boolean isRealType(TypeInformation<?> ti) {
    return !(ti instanceof NothingTypeInfo);
}

Try / catch

try {
    return ti.createSerializer(cfg);
} catch (RuntimeException e) {
    if (ti instanceof NothingTypeInfo) {
        throw new IllegalStateException(
            "Cannot serialize Nothing; fix the source's output type", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling createSerializer on a NothingTypeInfo instance; a pipeline branch that resolves to Nothing (e.g., DataStreamSource with out-type Nothing) and downstream code that requests a serializer for it; TypeExtractor falling back to Nothing and then a serializer being requested.

Common situations: Building operator chains where one input branch has no real type; using APIs that force serializer creation on a stream whose TypeInformation is Nothing; test fixtures that accidentally wire a Nothing-typed source into a sink or state.

Related errors


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