apache/flink · error · UnsupportedOperationException
Unsupported variant type: {}
Error message
Unsupported variant type: {} What it means
VariantSerializer only knows how to serialize the BinaryVariant concrete form (which carries value + metadata bytes). Its toBinaryVariant helper throws UnsupportedOperationException for any other Variant implementation, enforcing the invariant that the serializer receives the binary representation produced by the official builder.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/common/typeutils/base/VariantSerializer.java:115
public void copy(DataInputView source, DataOutputView target) throws IOException {
int valueLength = source.readInt();
int metadataLength = source.readInt();
target.writeInt(valueLength);
target.writeInt(metadataLength);
target.write(source, valueLength + metadataLength);
}
@Override
public TypeSerializerSnapshot<Variant> snapshotConfiguration() {
return new VariantSerializerSnapshot();
}
private BinaryVariant toBinaryVariant(Variant variant) {
if (variant instanceof BinaryVariant) {
return (BinaryVariant) variant;
}
throw new UnsupportedOperationException("Unsupported variant type: " + variant.getClass());
}
@Internal
public static final class VariantSerializerSnapshot
extends SimpleTypeSerializerSnapshot<Variant> {
/** Constructor to create snapshot from serializer (writing the snapshot). */
public VariantSerializerSnapshot() {
super(() -> INSTANCE);
}
}
}
View on GitHub (pinned to 2f3c205e92)
Solutions
- Always build Variant values through BinaryVariantBuilder (the public builder), whose build() returns a BinaryVariant that the serializer accepts.
- Route Variant data through the SQL/Table API, which converts to BinaryVariant automatically.
- If you hold a non-binary Variant, convert it to BinaryVariant before it reaches any serializer-backed sink/state.
- Do not implement the Variant interface yourself for data that will be serialized.
Example fix
// before: serializer.serialize(myCustomVariant); // throws: Unsupported variant type
// after: BinaryVariant bv = BinaryVariantBuilder.ofString("x").build(); // build() returns BinaryVariant
// serializer.serialize(bv); Defensive patterns
Strategy: type-guard
Type guard
static boolean isSerializableVariant(Variant v) {
return v instanceof BinaryVariant;
}
// usage before serialize:
if (!isSerializableVariant(myVariant)) {
BinaryVariant bv = BinaryVariantBuilder.ofString(myValue).build(); // rebuild as BinaryVariant
serializer.serialize(bv, target);
} else {
serializer.serialize(myVariant, target);
} Try / catch
try {
serializer.serialize(variant, target);
} catch (UnsupportedOperationException e) {
if (e.getMessage().contains("Unsupported variant type")) {
log.error("Variant must be a BinaryVariant; rebuild via BinaryVariantBuilder before serializing");
}
throw e;
} Prevention
- Always build Variant values with BinaryVariantBuilder, whose build() returns BinaryVariant.
- Route Variant data through the SQL/Table API, which converts to BinaryVariant automatically.
- Never implement the Variant interface yourself for data that will be serialized.
- Add an instanceof BinaryVariant guard at any custom serialization boundary.
When it happens
Trigger: Passing a Variant that is not a BinaryVariant to VariantSerializer.serialize/copy — e.g., a custom Variant implementation or a Variant built through a path that did not yield a BinaryVariant.
Common situations: Using the internal Variant API directly instead of the public SQL/Table path; implementing the Variant interface in a custom class and feeding it to a sink or keyed state typed with Variant; bypassing BinaryVariantBuilder.
Related errors
- Unable to serialize VARIANT value.
- Cannot deserialize and unwrap accumulators properly.
- Failed to serialize ExecutionPlan.
- Failed to deserialize coordination response
- Cannot deserialize and unwrap accumulators properly.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/a1838b3c2bdd9bf5.
Report an issue: GitHub.