apache/seatunnel · error · IllegalArgumentException

The Avro schema is not a nullable type: ${schema}

Error message

The Avro schema is not a nullable type: ${schema}

What it means

The nullable-wrapping converter expects an Avro schema that is either a plain type or a union of exactly two types where one is NULL; otherwise it throws IllegalArgumentException because it cannot unwrap the actual schema to delegate conversion.

Source

Thrown at seatunnel-connectors-v2/connector-hudi/src/main/java/org/apache/seatunnel/connectors/seatunnel/hudi/sink/convert/RowDataToAvroConverters.java:224

            private static final long serialVersionUID = 1L;

            @Override
            public Object convert(Schema schema, Object object) {
                if (object == null) {
                    return null;
                }

                // get actual schema if it is a nullable schema
                Schema actualSchema;
                if (schema.getType() == Schema.Type.UNION) {
                    List<Schema> types = schema.getTypes();
                    int size = types.size();
                    if (size == 2 && types.get(1).getType() == Schema.Type.NULL) {
                        actualSchema = types.get(0);
                    } else if (size == 2 && types.get(0).getType() == Schema.Type.NULL) {
                        actualSchema = types.get(1);
                    } else {
                        throw new IllegalArgumentException(
                                "The Avro schema is not a nullable type: " + schema);
                    }
                } else {
                    actualSchema = schema;
                }
                return converter.convert(actualSchema, object);
            }
        };
    }

    private static RowDataToAvroConverter createRowConverter(SeaTunnelRowType rowType) {
        final RowDataToAvroConverter[] fieldConverters =
                Arrays.stream(rowType.getFieldTypes())
                        .map(RowDataToAvroConverters::createConverter)
                        .toArray(RowDataToAvroConverter[]::new);
        final SeaTunnelDataType<?>[] fieldTypes = rowType.getFieldTypes();

        return new RowDataToAvroConverter() {

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Ensure the Avro schema fields are unions of the form [T, null] or [null, T] only
  2. Regenerate/normalize the Hudi table Avro schema so nullable fields use exactly two-branch unions
  3. Simplify multi-branch unions by picking a single type per field

Example fix

// before: field schema = union(string, int, null)
// after: field schema = union(string, null)
Defensive patterns

Strategy: type-guard

Validate before calling

// verify Avro field schemas are two-branch nullable unions
for (Schema.Field f : schema.getFields()) {
    Schema s = f.schema();
    if (s.getType() == Schema.Type.UNION) {
        List<Schema> ts = s.getTypes();
        boolean ok = ts.size() == 2 && (ts.get(0).getType() == Schema.Type.NULL || ts.get(1).getType() == Schema.Type.NULL);
        if (!ok) throw new IllegalArgumentException("Field " + f.name() + " union is not [T, null]");
    }
}

Type guard

static boolean isTwoBranchNullableUnion(Schema s) {
    if (s.getType() != Schema.Type.UNION) return false;
    List<Schema> ts = s.getTypes();
    return ts.size() == 2 && (ts.get(0).getType() == Schema.Type.NULL || ts.get(1).getType() == Schema.Type.NULL);
}

Try / catch

try {
    converter.convert(schema, value);
} catch (IllegalArgumentException e) {
    LOG.error("Avro schema not nullable-union shaped: {}", e.getMessage());
}

Prevention

When it happens

Trigger: convert() receives a schema that is a UNION with more than 2 members, or a 2-member union where neither member is NULL (e.g. [string, int]).

Common situations: Avro schema generated from Hudi table config with multi-type unions (default values of different types); schema evolution introducing [null, oldType, newType] unions; hand-written Avro schemas not following nullable conventions.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/9e3902a9cef0b989. Report an issue: GitHub.