apache/iceberg · error · IllegalStateException
Unknown type for binary field. Type name: " + bytes.getClass
Error message
Unknown type for binary field. Type name: " + bytes.getClass().getName()
What it means
StructRowData.getBinaryInternal converts the value stored in the wrapped StructLike into a Flink binary (byte[]). Only ByteBuffer, byte[], and UUID (Iceberg's fixed-length UUID representation) are supported; any other stored runtime type causes IllegalStateException with the class name, indicating the field's value doesn't match a binary/fixed/uuid column.
Source
Thrown at flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/data/StructRowData.java:238
return isNullAt(pos) ? null : getBinaryInternal(pos);
}
private byte[] getBinaryInternal(int pos) {
Object bytes = struct.get(pos, Object.class);
// should only be either ByteBuffer or byte[]
if (bytes instanceof ByteBuffer) {
return ByteBuffers.toByteArray((ByteBuffer) bytes);
} else if (bytes instanceof byte[]) {
return (byte[]) bytes;
} else if (bytes instanceof UUID) {
UUID uuid = (UUID) bytes;
ByteBuffer bb = ByteBuffer.allocate(16);
bb.putLong(uuid.getMostSignificantBits());
bb.putLong(uuid.getLeastSignificantBits());
return bb.array();
} else {
throw new IllegalStateException(
"Unknown type for binary field. Type name: " + bytes.getClass().getName());
}
}
@Override
public ArrayData getArray(int pos) {
return isNullAt(pos)
? null
: (ArrayData)
convertValue(type.fields().get(pos).type().asListType(), struct.get(pos, List.class));
}
@Override
public MapData getMap(int pos) {
return isNullAt(pos)
? null
: (MapData)
convertValue(type.fields().get(pos).type().asMapType(), struct.get(pos, Map.class));View on GitHub (pinned to 86d9c8fc54)
Solutions
- Look at the class in the message and normalize the stored value to ByteBuffer, byte[], or UUID upstream.
- If values are stored as Strings, decode them (base64 or UTF-8) before wrapping the row.
- Verify the read schema matches the physical column types so binary columns aren't served strings.
- Fix the custom StructLike implementation to return ByteBuffer for FIXED/BINARY fields, as StructRowData's convertValue path also assumes ByteBuffer.
Example fix
// before
byte[] b = structRowData.getBinary(pos); // fails for String-stored values
// after
Object raw = struct.get(pos, Object.class);
byte[] b = (raw instanceof String s)
? java.util.Base64.getDecoder().decode(s)
: structRowData.getBinary(pos); Defensive patterns
Strategy: validation
Validate before calling
Object raw = struct.get(pos, Object.class);
Preconditions.checkArgument(
raw == null || raw instanceof ByteBuffer || raw instanceof byte[] || raw instanceof UUID,
"binary field holds unexpected type: %s", raw == null ? "null" : raw.getClass()); Type guard
boolean isBinaryRepresentable(Object v) {
return v instanceof ByteBuffer || v instanceof byte[] || v instanceof UUID;
} Try / catch
try {
byte[] b = structRowData.getBinary(pos);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Unknown type for binary field")) {
log.error("Binary column at pos {} stores incompatible type", pos, e);
throw new SchemaMismatchException(e);
}
throw e;
} Prevention
- Store binary/fixed columns as ByteBuffer (or byte[]) and uuid as UUID in StructLike rows.
- Reject String-encoded binary at write time rather than hoping the reader decodes it.
When it happens
Trigger: Calling getBinary(pos) on StructRowData when the StructLike holds e.g. String, CharSequence, or a custom type rather than ByteBuffer/byte[]/UUID for a binary, fixed, or uuid column.
Common situations: Custom writer storing binary as base64 String; StructLike adapters (e.g. wrapping external records) mapping fixed/uuid fields to non-standard classes; schema mismatch where a string column is read through a binary-typed schema.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Unknown type for binary field. Type name: ${className}
- Unknown type for binary field. Type name:
- Unsupported binary type: + value.getClass()
- Unknown type for int field. Type name: ${className}
- Unknown type for long field. Type name: ${className}
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/95052117b9cce3fd.
Report an issue: GitHub.