apache/iceberg · error · UnsupportedOperationException

Not a supported type

Error message

Not a supported type: ${targetType}

What it means

DataConverter.get() dispatches on the root Flink LogicalType of the source/target pair and only supports ROW, ARRAY, and MAP roots when building converters. Any other top-level type (or an unhandled case) falls into the default branch and throws UnsupportedOperationException naming the offending type. Row-level primitive types are handled at the field level elsewhere, so hitting this means an unexpected root type reached the converter factory.

Solutions

  1. Ensure the types passed to DataConverter.get() are RowType-based (full table rows), not bare primitive types
  2. Add a case to the switch in DataConverter.get() if the new root type genuinely needs support
  3. Log/inspect the targetType value in the message to identify which unexpected type is flowing in

Example fix

// before
DataConverter.get(rowDataType, intType); // throws
// after
DataConverter.get(sourceRowType, targetRowType);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(sourceType instanceof RowType)) {
  throw new IllegalArgumentException("Expected RowType root, got: " + sourceType);
}

Type guard

boolean isSupportedRoot(LogicalType t) {
  switch (t.getTypeRoot()) {
    case ROW:
    case ARRAY:
    case MAP:
      return true;
    default:
      return false;
  }
}

Try / catch

try {
  converter = DataConverter.get(sourceType, targetType);
} catch (UnsupportedOperationException e) {
  // handle unsupported root type: log targetType and fall back / fail fast
}

Prevention

When it happens

Trigger: Calling DataConverter.get(sourceType, targetType) with a root LogicalType other than ROW, ARRAY, or MAP (e.g. a bare IntType, VarCharType, or an unsupported composite type).

Common situations: A table schema change reduced the row to something the dynamic sink's converter dispatch does not handle; an upstream refactor passes a flattened column type instead of a RowType; a new Flink type family not yet covered by the switch.

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

Appendix: source

Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/sink/dynamic/DataConverter.java:127

        };
      case TIMESTAMP_WITHOUT_TIME_ZONE:
        return object -> {
          if (object instanceof Integer) {
            LocalDateTime dateTime =
                LocalDateTime.of(LocalDate.ofEpochDay((Integer) object), LocalTime.MIN);
            return TimestampData.fromLocalDateTime(dateTime);
          } else {
            return object;
          }
        };
      case ROW:
        return new RowDataConverter((RowType) sourceType, (RowType) targetType);
      case ARRAY:
        return new ArrayConverter((ArrayType) sourceType, (ArrayType) targetType);
      case MAP:
        return new MapConverter((MapType) sourceType, (MapType) targetType);
      default:
        throw new UnsupportedOperationException("Not a supported type: " + targetType);
    }
  }

  static DataConverter nullable(DataConverter converter) {
    return value -> value == null ? null : converter.convert(value);
  }

  class RowDataConverter implements DataConverter {
    private final RowData.FieldGetter[] fieldGetters;
    private final DataConverter[] dataConverters;

    RowDataConverter(RowType sourceType, RowType targetType) {
      this.fieldGetters = new RowData.FieldGetter[targetType.getFields().size()];
      this.dataConverters = new DataConverter[targetType.getFields().size()];

      for (int i = 0; i < targetType.getFields().size(); i++) {
        RowData.FieldGetter fieldGetter;
        DataConverter dataConverter;

View on GitHub (pinned to 86d9c8fc54)