apache/iceberg · error
Unsupported binary type: + value.getClass()
Error message
Unsupported binary type: + value.getClass()
What it means
Thrown by TransformUtil-backed toHumanString() when rendering a BINARY-transformed value whose runtime type is neither ByteBuffer nor byte[]. Iceberg's human-string rendering of binary values base64-encodes ByteBuffer or byte[] inputs; any other object type cannot be encoded and the method fails fast with the unexpected class name.
Source
Thrown at api/src/main/java/org/apache/iceberg/transforms/Transform.java:197
if (((Types.TimestampType) type).shouldAdjustToUTC()) {
return TransformUtil.humanTimestampWithZone((Long) value);
} else {
return TransformUtil.humanTimestampWithoutZone((Long) value);
}
case TIMESTAMP_NANO:
if (((Types.TimestampNanoType) type).shouldAdjustToUTC()) {
return TransformUtil.humanTimestampNanoWithZone((Long) value);
} else {
return TransformUtil.humanTimestampNanoWithoutZone((Long) value);
}
case FIXED:
case BINARY:
if (value instanceof ByteBuffer) {
return TransformUtil.base64encode(((ByteBuffer) value).duplicate());
} else if (value instanceof byte[]) {
return TransformUtil.base64encode(ByteBuffer.wrap((byte[]) value));
} else {
throw new UnsupportedOperationException("Unsupported binary type: " + value.getClass());
}
default:
return value.toString();
}
}
/**
* Return the unique transform name to check if similar transforms for the same source field are
* added multiple times in partition spec builder.
*
* @return a name used for dedup
*/
default String dedupName() {
return toString();
}
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Pass the value as java.nio.ByteBuffer or byte[] when rendering binary transform values
- Convert other types first: ByteBuffer.wrap(stringValue.getBytes(StandardCharsets.ISO_8859_1)) only if the string truly holds raw bytes
- Catch UnsupportedOperationException and convert/handle unexpected types explicitly
Example fix
// before
String s = transform.toHumanString("raw-bytes");
// after
String s = transform.toHumanString(ByteBuffer.wrap("raw-bytes".getBytes(StandardCharsets.UTF_8))); Defensive patterns
Strategy: type-guard
Validate before calling
if (!(value instanceof ByteBuffer) && !(value instanceof byte[])) {
throw new IllegalArgumentException("Binary transform values must be ByteBuffer or byte[]");
} Type guard
boolean isBinaryValue(Object v) {
return v instanceof ByteBuffer || v instanceof byte[];
} Try / catch
try { return transform.toHumanString(value); } catch (UnsupportedOperationException e) { return Base64.getEncoder().encodeToString(toBytes(value)); } Prevention
- Always pass ByteBuffer or byte[] for binary column values
- Normalize deserialized binary data to ByteBuffer before partition rendering
- Add a type check before calling toHumanString on binary transforms
When it happens
Trigger: Calling toHumanString(value) on a bound binary transform (e.g. Transforms.identity().bind(BinaryType.get())) with a value that is neither ByteBuffer nor byte[] — e.g. a String, an InputStream, or a custom wrapper type.
Common situations: Passing String-encoded binary data instead of raw bytes/ByteBuffer into partition-value rendering; custom deserializers producing non-standard types for binary columns.
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
- Unsupported time unit: + granularity
- Unsupported time unit: + timestampUnit
- apply(value) is deprecated, use bind(Type).apply(value)
- bind is not implemented
- Cannot truncate type: + type
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/460efde0ccbca21f.
Report an issue: GitHub.