apache/iceberg · error · IllegalArgumentException
Cannot create writer for non-option union
Error message
Cannot create writer for non-option union: %s
What it means
Validation in BaseWriteBuilder.union: an Avro union schema for an optional field must have exactly two branches (null + type) to map to Iceberg's optional model. The %s is the union schema; the check fails when the union has more (or fewer) than two types, i.e. the schema is not a nullable option.
Solutions
- Rewrite the Avro schema so nullable fields are two-branch unions of null and the value type
- Flatten multi-branch unions into separate optional fields before writing
- Validate the schema shape before handing it to the Avro writer builder
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at core/src/main/java/org/apache/iceberg/avro/BaseWriteBuilder.java:48 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/1d3f1637f0766ffa.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/avro/BaseWriteBuilder.java:48
protected abstract ValueWriter<?> fixedWriter(int length);
@Override
public ValueWriter<?> record(Schema record, List<String> names, List<ValueWriter<?>> fields) {
return createRecordWriter(fields);
}
@Override
public ValueWriter<?> union(Schema union, List<ValueWriter<?>> options) {
Preconditions.checkArgument(
options.size() == 2, "Cannot create writer for non-option union: %s", union);
if (union.getTypes().get(0).getType() == Schema.Type.NULL) {
return ValueWriters.option(0, options.get(1));
} else if (union.getTypes().get(1).getType() == Schema.Type.NULL) {
return ValueWriters.option(1, options.get(0));
} else {
throw new IllegalArgumentException(
String.format("Cannot create writer for non-option union: %s", union));
}
}
@Override
public ValueWriter<?> array(Schema array, ValueWriter<?> elementWriter) {
if (array.getLogicalType() instanceof LogicalMap) {
ValueWriters.StructWriter<?> keyValueWriter = (ValueWriters.StructWriter<?>) elementWriter;
return ValueWriters.arrayMap(keyValueWriter.writer(0), keyValueWriter.writer(1));
}
return ValueWriters.array(elementWriter);
}
@Override
public ValueWriter<?> map(Schema map, ValueWriter<?> valueWriter) {
return ValueWriters.map(ValueWriters.strings(), valueWriter);
}
View on GitHub (pinned to 86d9c8fc54)