apache/iceberg · error · java.lang.UnsupportedOperationException

Unsupported DistinctType.

Error message

Unsupported DistinctType.

What it means

Flink DistinctType is a user-defined distinct logical type with no Iceberg counterpart, so FlinkTypeVisitor throws UnsupportedOperationException when a conversion visitor encounters it. Iceberg schemas cannot represent this type, so conversion is rejected.

Source

Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/FlinkTypeVisitor.java:53

  @Override
  public T visit(ZonedTimestampType zonedTimestampType) {
    throw new UnsupportedOperationException("Unsupported ZonedTimestampType.");
  }

  @Override
  public T visit(YearMonthIntervalType yearMonthIntervalType) {
    throw new UnsupportedOperationException("Unsupported YearMonthIntervalType.");
  }

  @Override
  public T visit(DayTimeIntervalType dayTimeIntervalType) {
    throw new UnsupportedOperationException("Unsupported DayTimeIntervalType.");
  }

  @Override
  public T visit(DistinctType distinctType) {
    throw new UnsupportedOperationException("Unsupported DistinctType.");
  }

  @Override
  public T visit(StructuredType structuredType) {
    throw new UnsupportedOperationException("Unsupported StructuredType.");
  }

  @Override
  public T visit(NullType nullType) {
    throw new UnsupportedOperationException("Unsupported NullType.");
  }

  @Override
  public T visit(RawType<?> rawType) {
    throw new UnsupportedOperationException("Unsupported RawType.");
  }

  @Override

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Replace the DistinctType column with its underlying base type (e.g. DataTypes.INT or STRING).
  2. Cast the column to its underlying type in SQL, e.g. CAST(distinct_col AS INT), before the Iceberg sink.
  3. Avoid DataTypes.DISTINCT in table definitions written to Iceberg; use a plain type plus application-level validation.
  4. Override visit(DistinctType) in a custom FlinkTypeVisitor subclass to map it to the underlying Iceberg type.

Example fix

// before
DataTypes.DISTINCT("userId", DataTypes.BIGINT())
// after
DataTypes.BIGINT() // plain type; enforce semantics in application code
Defensive patterns

Strategy: validation

Validate before calling

import org.apache.flink.table.types.logical.DistinctType;
import org.apache.flink.table.types.logical.LogicalType;

static boolean containsDistinctType(org.apache.flink.table.api.Schema schema) {
  return schema.getColumns().stream()
      .anyMatch(c -> c.getType().getLogicalType() instanceof DistinctType);
}

Type guard

static boolean isDistinctType(LogicalType t) {
  return t instanceof DistinctType;
}

Prevention

When it happens

Trigger: Converting a row type containing a column whose logical type is a Flink DistinctType, e.g. created via DataTypes.DISTINCT(...) or registered distinct UDTs, during schema conversion for an Iceberg sink or catalog operation.

Common situations: Using DataTypes.DISTINCT in Table API columns feeding an Iceberg sink; connector/UDF outputs that emit distinct-typed columns; schemas copied from codebases using Flink's advanced type system.

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/b627e1f04e0c2e0c. Report an issue: GitHub.