apache/iceberg · error

Cannot serialize type: + typeId

Error message

Cannot serialize type: + typeId

What it means

Conversions.toByteBuffer maps each primitive typeId to its spec-defined binary encoding and throws UnsupportedOperationException for typeIds it cannot serialize. This happens for types with no serialization definition in this client version (e.g. unknown/unsupported new spec types) or for a value passed with a mismatched typeId.

Source

Thrown at api/src/main/java/org/apache/iceberg/types/Conversions.java:145

        VariantMetadata variantMetadata = variant.metadata();
        VariantValue variantValue = variant.value();
        ByteBuffer variantBuffer =
            ByteBuffer.allocate(variantMetadata.sizeInBytes() + variantValue.sizeInBytes())
                .order(ByteOrder.LITTLE_ENDIAN);
        variantMetadata.writeTo(variantBuffer, 0);
        variantValue.writeTo(variantBuffer, variantMetadata.sizeInBytes());
        return variantBuffer;
      case GEOMETRY:
      case GEOGRAPHY:
        // Geometry and geography lower/upper bounds are single points encoded as an
        // x:y:z:m concatenation of 8-byte little-endian IEEE 754 doubles. See the
        // Bound Serialization section of the Iceberg spec.
        return ((GeospatialBound) value).toByteBuffer();
      case UNKNOWN:
        // underlying type not known
        return null;
      default:
        throw new UnsupportedOperationException("Cannot serialize type: " + typeId);
    }
  }

  @SuppressWarnings("unchecked")
  public static <T> T fromByteBuffer(Type type, ByteBuffer buffer) {
    return (T) internalFromByteBuffer(type, buffer);
  }

  private static Object internalFromByteBuffer(Type type, ByteBuffer buffer) {
    if (buffer == null) {
      return null;
    }

    ByteBuffer tmp = buffer.duplicate();
    if (type == Types.UUIDType.get() || type instanceof Types.DecimalType) {
      tmp.order(ByteOrder.BIG_ENDIAN);
    } else {
      tmp.order(ByteOrder.LITTLE_ENDIAN);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Upgrade the Iceberg version to one that serializes the type
  2. Skip fields whose typeId is unsupported before calling toByteBuffer
  3. Ensure the Type passed matches the actual value's type

Example fix

// before
for (Types.NestedField f : schema.columns()) {
  Object ser = Conversions.toByteBuffer(f.type(), values.get(f.fieldId())); // throws for unknown
}
// after
for (Types.NestedField f : schema.columns()) {
  if (f.type() instanceof Types.UnknownType) continue;
  Object ser = Conversions.toByteBuffer(f.type(), values.get(f.fieldId()));
}
Defensive patterns

Strategy: validation

Validate before calling

if (type.typeId() == Type.TypeID.UNKNOWN) skip; else serialize;

Type guard

boolean serializable(Type t) { return t.typeId() != Type.TypeID.UNKNOWN; }

Try / catch

try { buf = Conversions.toByteBuffer(type, v); } catch (UnsupportedOperationException e) { buf = null; }

Prevention

When it happens

Trigger: Serializing a value whose typeId falls into the default branch — typically UNKNOWN types or a spec type (variant, new geo kinds) added after this Iceberg version; passing the wrong Type alongside a value.

Common situations: Writing statistics/partition values containing fields of newer spec types with an older client; generic serialization code that iterates all fields of a schema including unserializable ones.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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