apache/flink · error · UnsupportedOperationException

Avro Union with NULL type is only supported. Unsupported typ

Error message

Avro Union with NULL type is only supported. Unsupported types: {}

What it means

AvroToVariantDataConverters only supports Avro unions of the shape [null, T] or [T, null]. If filtering out NULL branches leaves zero or more than one non-null branch, converter construction throws UnsupportedOperationException listing the full union type list.

Source

Thrown at flink-formats/flink-avro/src/main/java/org/apache/flink/formats/avro/AvroToVariantDataConverters.java:155

                        createNullableConverter(elementSchema);
                return createArrayConverter(elementConverter);

            case MAP:
                Schema valueSchema = schema.getValueType();
                AvroToVariantDataConverter valueConverter = createNullableConverter(valueSchema);
                return createMapConverter(valueConverter);

            case UNION:
                // Handle nullable types (union with null)
                List<Schema> nonNullUnionType =
                        schema.getTypes().stream()
                                .filter(t -> t.getType() != Schema.Type.NULL)
                                .collect(Collectors.toList());

                if (nonNullUnionType.size() == 1) {
                    return createNullableConverter(nonNullUnionType.get(0));
                } else {
                    throw new UnsupportedOperationException(
                            "Avro Union with NULL type is only supported. Unsupported types: "
                                    + schema.getTypes());
                }

            default:
                throw new UnsupportedOperationException("Unsupported type: " + schema.getType());
        }
    }

    /** Creates an array converter that works directly with Avro elements. */
    private static AvroToVariantDataConverter createArrayConverter(
            AvroToVariantDataConverter elementConverter) {
        return (avroObject) -> {
            List<?> list = (List<?>) avroObject;
            VariantBuilder.VariantArrayBuilder variantArrayBuilder = SHARED_BUILDER.array();

            for (Object item : list) {
                Variant convertedItem = elementConverter.convert(item);

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Restructure the union to at most one non-null branch plus null: ["null", T].
  2. Flatten multi-branch unions into a wrapper record or convert them to a single concrete type before the Variant conversion.
  3. If you control the producer, emit VARIANT-native data instead of union-heavy Avro.

Example fix

// before
{"name":"v","type":["null","string","int"]}

// after
{"name":"v","type":["null","string"]} // pick one concrete branch; encode ints as strings if needed
Defensive patterns

Strategy: validation

Validate before calling

static void validateUnionForVariant(Schema s) {
    if (s.getType() == Schema.Type.UNION) {
        long nonNull = s.getTypes().stream().filter(t -> t.getType() != Schema.Type.NULL).count();
        if (nonNull != 1) {
            throw new IllegalArgumentException("Union must be [null,T] for VARIANT: " + s);
        }
    }
}

Type guard

static boolean isNullableUnion(Schema s) {
    return s.getType() == Schema.Type.UNION
            && s.getTypes().stream().filter(t -> t.getType() != Schema.Type.NULL).count() == 1;
}

Prevention

When it happens

Trigger: An Avro schema field with type ["null","string","int"] or any multi-alternative union is converted to Variant; also a union of only nulls (nonNullUnionType.size() != 1).

Common situations: Ingesting arbitrary .avsc files (schema-on-read to VARIANT) where unions have 2+ non-null branches; Avro IDL generated from JSON with optional-ish typing; Confluent schemas with complex unions.

Related errors


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