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

  1. Pass the value as java.nio.ByteBuffer or byte[] when rendering binary transform values
  2. Convert other types first: ByteBuffer.wrap(stringValue.getBytes(StandardCharsets.ISO_8859_1)) only if the string truly holds raw bytes
  3. 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

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/460efde0ccbca21f. Report an issue: GitHub.