apache/iceberg · error · IllegalArgumentException
The Avro schema is not a nullable type: " + schema.toString(
Error message
The Avro schema is not a nullable type: " + schema.toString()
What it means
The nullable-wrapping converter in RowDataToAvroConverters expects the Avro schema for a field to be either a plain type or a union of exactly two branches where one is NULL. When convert() encounters a union that is not of the shape [T, null] or [null, T] (e.g. a 3-branch union, a single non-null type, or a union of two non-null types), it throws IllegalArgumentException.
Source
Thrown at flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/formats/avro/RowDataToAvroConverters.java:292
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.toString());
}
} else {
actualSchema = schema;
}
return converter.convert(actualSchema, object);
}
};
}
private static RowDataToAvroConverter createRowConverter(
RowType rowType, boolean legacyTimestampMapping) {
final RowDataToAvroConverter[] fieldConverters =
rowType.getChildren().stream()
.map(legacyType -> createConverter(legacyType, legacyTimestampMapping))
.toArray(RowDataToAvroConverter[]::new);
final LogicalType[] fieldTypes =
rowType.getFields().stream().map(RowType.RowField::getType).toArray(LogicalType[]::new);View on GitHub (pinned to 86d9c8fc54)
Solutions
- Flatten the Avro schema so nullable fields are unions of exactly one type plus null, e.g. ["null", "int"].
- Extract the matching non-null branch schema and pass that to convert() when handling a branch yourself.
- Regenerate/normalize the schema from the Flink/LogicalType via AvroSchemaConverter.convertToSchema instead of supplying a custom union schema.
- If multi-branch unions are required, map them to a Flink ROW with nullable fields before serialization.
Example fix
// before
{"type":["null","int","string"]}
// after
{"type":["null","string"]} // single nullable type per field Defensive patterns
Strategy: validation
Validate before calling
Schema actual = schema;
if (actual.getType() == Schema.Type.UNION) {
List<Schema> types = actual.getTypes();
boolean ok = types.size() == 2 && (types.get(0).getType() == Schema.Type.NULL || types.get(1).getType() == Schema.Type.NULL);
if (!ok) throw new IllegalArgumentException("Field must be [T, null] union, got: " + actual);
} Try / catch
try { return converter.convert(schema, value); } catch (IllegalArgumentException e) { /* normalize the schema (flatten unions) and retry once */ } Prevention
- Generate Avro schemas via AvroSchemaConverter.convertToSchema rather than hand-writing unions.
- Keep nullable fields as exactly ["null", T] unions.
- Validate third-party schemas on ingestion before registering them for writers.
When it happens
Trigger: Calling convert(schema, object) where schema is a UNION type with more than 2 branches, or 2 branches neither of which is NULL, or where the converter was not built for a nullable schema.
Common situations: Hand-written or third-party Avro schemas with multi-branch unions (e.g. [null, int, string]) fed to a RowData-to-Avro writer; schema evolved to add extra union branches; passing the outer union instead of a branch schema.
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 logical type: ${logicalType}
- The Avro schema is not a nullable type: ${schema}
- Unsupported Avro type '${schema.getType()}'.
- The Avro schema is not a nullable type: ${schema.toString()}
- Could not parse Avro schema string.
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/65314082c1a09056.
Report an issue: GitHub.