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.
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.
- A TypeInfoFactory for type
- Avro Union with NULL type is only supported. Unsupported…
- Buffer too small: capacity
- Buffer underflow.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/a1838b3c2bdd9bf5.
Report an issue: GitHub.
Appendix: 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)