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
StructInternalRow.getBinaryInternal materializes a Spark BINARY column from the underlying field, which Iceberg stores as either ByteBuffer or byte[]. Any other Java class means the stored object doesn't match the declared binary type, so it throws IllegalStateException with the actual class name.
Source
Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java:201
CharSequence seq = struct.get(ordinal, CharSequence.class);
return UTF8String.fromString(seq.toString());
}
@Override
public byte[] getBinary(int ordinal) {
return isNullAt(ordinal) ? null : getBinaryInternal(ordinal);
}
private byte[] getBinaryInternal(int ordinal) {
Object bytes = struct.get(ordinal, 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 {
throw new IllegalStateException(
"Unknown type for binary field. Type name: " + bytes.getClass().getName());
}
}
@Override
public CalendarInterval getInterval(int ordinal) {
throw new UnsupportedOperationException("Unsupported type: interval");
}
@Override
public InternalRow getStruct(int ordinal, int numFields) {
return isNullAt(ordinal) ? null : getStructInternal(ordinal);
}
private InternalRow getStructInternal(int ordinal) {
return new StructInternalRow(
type.fields().get(ordinal).type().asStructType(), struct.get(ordinal, StructLike.class));
}View on GitHub (pinned to 86d9c8fc54)
Solutions
- Ensure the producer stores ByteBuffer or byte[] for binary fields
- Check the class name in the message and convert at the producer (e.g. wrap byte[] in ByteBuffer or call array())
- Verify the expected Spark schema matches the table's Iceberg type (BinaryType vs StringType mixups are common)
- Upgrade/rebuild against the same Iceberg version used to write, so Java class mappings agree
Example fix
// before byte[] b = row.getBinaryInternal(ordinal); // stored String -> IllegalStateException // after // fix producer: struct.set(ordinal, ByteBuffer.wrap(stringValue.getBytes(StandardCharsets.UTF_8)));
Defensive patterns
Strategy: type-guard
Validate before calling
Object v = struct.get(pos, javaClass);
if (!(v instanceof ByteBuffer) && !(v instanceof byte[])) {
throw new IllegalStateException("expected ByteBuffer or byte[] for binary field, got " + v.getClass());
} Type guard
boolean isBinaryBacked(Object v) { return v instanceof ByteBuffer || v instanceof byte[]; } Try / catch
try { byte[] b = row.getBinaryInternal(ordinal); } catch (IllegalStateException e) { /* convert or fix the producer to store ByteBuffer/byte[] */ } Prevention
- Store binary columns as ByteBuffer or byte[] in custom struct wrappers
- Don't declare a column BinaryType if values were written as strings
- Verify schema compatibility after table type evolutions
When it happens
Trigger: Reading a column declared as Spark BinaryType while the Iceberg struct actually contains e.g. String, ByteString, or a heap ByteBuffer subtype that failed boxing expectations — a schema/value type mismatch between producer and reader.
Common situations: Custom row wrappers storing non-standard types in the struct; schema drift where the field changed type after being written; wrong expected schema in a custom scan.
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: ${bytes.getClass()
- Unknown type for int field. Type name: ${integer.getClass().
- Unknown type for long field. Type name: ${longVal.getClass()
- Unknown type for int field. Type name: " + integer.getClass(
- Unknown type for long field. Type name: " + longVal.getClass
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/6ac9977954b280da.
Report an issue: GitHub.