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

  1. 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
  2. Verify writer and reader use compatible Iceberg versions for the table format
  3. Inspect the custom value source (FileIO/catalog plugin) that supplies binary column values
  4. 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

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


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)