apache/iceberg · error · UnsupportedOperationException
Field %d has unsupported field type: %s
Error message
Field %d has unsupported field type: %s
What it means
SortKeySerializer.serialize() flattens each SortKey field into the DataOutputView by switching on the Iceberg type id. Numeric/text/temporal/primitive types are supported, but STRUCT, MAP, LIST (and the default arm) are not — the SortKey representation is a flattened struct without nested collections, so serialize throws UnsupportedOperationException identifying the field id and type. The table's sort order contains a column with a nested/complex type.
Source
Thrown at flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/sink/shuffle/SortKeySerializer.java:197
case FIXED:
case BINARY:
byte[] bytes = record.get(i, ByteBuffer.class).array();
target.writeInt(bytes.length);
target.write(bytes);
break;
case DECIMAL:
BigDecimal decimal = record.get(i, BigDecimal.class);
byte[] decimalBytes = decimal.unscaledValue().toByteArray();
target.writeInt(decimalBytes.length);
target.write(decimalBytes);
target.writeInt(decimal.scale());
break;
case STRUCT:
case MAP:
case LIST:
default:
// SortKey transformation is a flattened struct without list and map
throw new UnsupportedOperationException(
String.format(
Locale.ROOT, "Field %d has unsupported field type: %s", fieldId, typeId));
}
}
}
@Override
public SortKey deserialize(DataInputView source) throws IOException {
// copying is a little faster than constructing a new SortKey object
SortKey deserialized = lazySortKey().copy();
deserialize(deserialized, source);
return deserialized;
}
@Override
public SortKey deserialize(SortKey reuse, DataInputView source) throws IOException {
Preconditions.checkArgument(
reuse.size() == size,View on GitHub (pinned to 86d9c8fc54)
Solutions
- Rewrite the table sort order to use only primitive-typed columns (no struct/map/list).
- Sort on a primitive component of the nested field (e.g. a top-level string/long extracted by the upstream job) instead of the nested column.
- Change write.distribution.mode to 'hash' (on a primitive key) or 'none' to avoid serializing SortKeys.
- Check the schema with a tool like DESCRIBE TABLE and confirm each sort column's type before enabling sorted writes.
Example fix
// before ALTER TABLE t WRITE ORDERED BY tags; -- tags is list<string> // after ALTER TABLE t WRITE ORDERED BY user_id, created_at;
Defensive patterns
Strategy: validation
Validate before calling
table.sortOrder().fields().forEach(f -> {
Type t = schema.findType(f.sourceId());
Preconditions.checkArgument(t.isPrimitiveType(),
"Sort column %s must be primitive, found %s", f.sourceId(), t);
}); Type guard
boolean sortKeySafe(Type t) {
return t.isPrimitiveType();
} Try / catch
try {
serializer.serialize(sortKey, view);
} catch (UnsupportedOperationException e) {
LOG.error("Sort order uses unsupported nested column; fix table sort order", e);
throw e;
} Prevention
- Inspect the table sort order and schema before enabling sorted writes in Flink.
- Never include struct/map/list columns in WRITE ORDERED BY.
- Re-check sort order after schema evolution.
When it happens
Trigger: Configuring a table sort order that includes a struct, map, or list column, then running a sorted write (write.distribution.mode=range or sorted write) in Flink so SortKey values must be serialized for the shuffle or sketch.
Common situations: Defining ALTER TABLE ... ORDER BY on a column of type map/list/struct by mistake; sort order inherited from Spark where nested sort keys behave differently; schema evolution adding a nested column into the sort spec.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Unsupported Avro type '${schema.getType()}'.
- Field %d has unsupported field type: %s
- Unsupported element type: ${elementType}
- Unsupported Avro type '${schema.getType()}'.
- Not a supported type: ${targetType}
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/4827c4f6746c4f6d.
Report an issue: GitHub.