{"record":{"id":"245a04906bc2dd70","repo":"apache/iceberg","slug":"unknown-type-for-binary-field-type-name-bytes-245a04","errorCode":null,"errorMessage":"Unknown type for binary field. Type name: ${bytes.getClass().getName()}","messagePattern":"Unknown type for binary field\\. Type name: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java","lineNumber":195,"sourceCode":"    CharSequence seq = struct.get(ordinal, CharSequence.class);\n    return UTF8String.fromString(seq.toString());\n  }\n\n  @Override\n  public byte[] getBinary(int ordinal) {\n    return isNullAt(ordinal) ? null : getBinaryInternal(ordinal);\n  }\n\n  private byte[] getBinaryInternal(int ordinal) {\n    Object bytes = struct.get(ordinal, Object.class);\n\n    // should only be either ByteBuffer or byte[]\n    if (bytes instanceof ByteBuffer) {\n      return ByteBuffers.toByteArray((ByteBuffer) bytes);\n    } else if (bytes instanceof byte[]) {\n      return (byte[]) bytes;\n    } else {\n      throw new IllegalStateException(\n          \"Unknown type for binary field. Type name: \" + bytes.getClass().getName());\n    }\n  }\n\n  @Override\n  public CalendarInterval getInterval(int ordinal) {\n    throw new UnsupportedOperationException(\"Unsupported type: interval\");\n  }\n\n  @Override\n  public InternalRow getStruct(int ordinal, int numFields) {\n    return isNullAt(ordinal) ? null : getStructInternal(ordinal);\n  }\n\n  private InternalRow getStructInternal(int ordinal) {\n    return new StructInternalRow(\n        type.fields().get(ordinal).type().asStructType(), struct.get(ordinal, StructLike.class));\n  }","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java#L177-L213","documentation":"getBinaryInternal extracts binary column values and only accepts ByteBuffer or byte[] from the underlying StructLike. Any other object type (String, Array[Byte] wrappers, custom types) throws IllegalStateException reporting the found class. It backs getBinary, getGeometry, getGeography, and binary view getters.","triggerScenarios":"A binary/geometry/geography column whose StructLike value is neither ByteBuffer nor byte[] — e.g. a custom producer storing UTF8String or a deserialization bug producing a wrong wrapper type.","commonSituations":"Custom readers or test fixtures populating binary fields with Strings; ORM/record adapters converting binary to unexpected Java types; geometry column values built by hand.","solutions":["Ensure binary-typed fields store ByteBuffer or byte[] in the StructLike","Convert before read: wrap byte[] in ByteBuffer or copy the ByteBuffer via ByteBuffers.toByteArray yourself","Use the message's class name to locate the offending producer and fix its conversion","If you consume via getBinary, defensively fetch with get(ordinal, null) and normalize"],"exampleFix":"// before\nbyte[] b = row.getBinary(ordinal); // value is String\n// after\nObject raw = row.get(ordinal, null);\nbyte[] b = raw instanceof String\n    ? ((String) raw).getBytes(StandardCharsets.UTF_8)\n    : row.getBinary(ordinal);","handlingStrategy":"type-guard","validationCode":"Object v = row.get(ordinal, null);\nif (!(v instanceof ByteBuffer) && !(v instanceof byte[])) {\n  throw new IllegalStateException(\"Unexpected binary-field value: \" + v.getClass());\n}","typeGuard":"boolean isBinaryCompatible(Object v) { return v instanceof ByteBuffer || v instanceof byte[]; }","tryCatchPattern":"try {\n  return row.getBinary(ordinal);\n} catch (IllegalStateException e) {\n  throw new IllegalStateException(\"Binary field held unexpected Java type\", e);\n}","preventionTips":["Always store binary as ByteBuffer or byte[]","Avoid String-encoded binary in custom producers","Cover binary/geometry columns in reader tests"],"tags":["spark","binary","type-mismatch","internalrow"],"backgroundTag":"type-mismatch","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}