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
- Ensure the Avro schema fields are unions of the form [T, null] or [null, T] only
- Regenerate/normalize the Hudi table Avro schema so nullable fields use exactly two-branch unions
- 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
- Generate Hudi table schemas with consistent [null, T] unions
- Avoid multi-type unions in schema evolution (single type per field)
- Validate Avro schema shape in CI before deploying jobs
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
- Unsupported to derive Schema for type: ${dataType}
- Avro format doesn't support non-string as key type of map. T
- Unsupported type: ${dataType}
- Fail to serialize at field: ${fieldName}.
- TABLE_SCHEMA_GET_FAILED
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/9e3902a9cef0b989.
Report an issue: GitHub.