apache/iceberg · error · IllegalStateException
Unknown type for binary field. Type name:
Error message
Unknown type for binary field. Type name:
What it means
toByteArray in StructInternalRow converts a binary field value into a byte[]. If the stored value is neither a ByteBuffer nor a byte[], Iceberg throws IllegalStateException because it cannot interpret the object as binary data. This indicates internal type corruption or misuse of the row accessor rather than an expected user error.
Solutions
- Check which class name is printed in the message and find where that value type is written; convert it to ByteBuffer/byte[] at write time
- Verify writer and reader use compatible Iceberg versions for the table format
- Inspect the custom value source (FileIO/catalog plugin) that supplies binary column values
- If caused by Iceberg itself, report/upgrade to a fixed version
Example fix
// before: passing a String-wrapped value into a binary field row.set(ordinal, someString); // after row.set(ordinal, ByteBuffer.wrap(someString.getBytes(StandardCharsets.UTF_8)));
Defensive patterns
Strategy: type-guard
Validate before calling
Object v = row.get(ordinal);
if (!(v instanceof ByteBuffer) && !(v instanceof byte[])) {
throw new IllegalArgumentException("Unexpected binary value type: " + v.getClass());
} Type guard
static boolean isSupportedBinary(Object v) {
return v instanceof ByteBuffer || v instanceof byte[];
} Try / catch
try {
byte[] b = row.getBinary(ordinal);
} catch (IllegalStateException e) {
log.error("Unsupported binary value in column {}: {}", ordinal, e.getMessage());
} Prevention
- Only write ByteBuffer or byte[] into binary columns
- Keep writer and reader Iceberg versions aligned
- Test cross-engine table reads in CI
When it happens
Trigger: Reading a Spark row via StructInternalRow where getBinaryInternal returns an object that is neither ByteBuffer nor byte[] — e.g. a custom or unexpected value object stored in a binary column, or a version mismatch between the writer that stored the value and the reader.
Common situations: Reading tables written by other engines/writers that stored binary values in unexpected Java types; custom catalog or FileIO integrations that bypass standard value conversions; upgrading Iceberg versions where internal representation changed.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Unknown dummy vector holder:
- Unknown dummy vector holder
- Unknown dummy vector holder
- Unknown type for binary field. Type name: " +…
- Unknown type for binary field. Type name
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/986f6ae2411ae322.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java:205
return UTF8String.fromString(seq.toString());
}
@Override
public byte[] getBinary(int ordinal) {
return isNullAt(ordinal) ? null : getBinaryInternal(ordinal);
}
private byte[] getBinaryInternal(int ordinal) {
return toByteArray(struct.get(ordinal, Object.class));
}
private static byte[] toByteArray(Object bytes) {
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 BinaryView getBinaryView(int ordinal) {
return isNullAt(ordinal)
? null
: toBinaryView(type.fields().get(ordinal).type(), getBinaryInternal(ordinal));
}
@Override
public CalendarInterval getInterval(int ordinal) {
throw new UnsupportedOperationException("Unsupported type: interval");
}
@Override
public InternalRow getStruct(int ordinal, int numFields) {View on GitHub (pinned to 86d9c8fc54)