apache/iceberg · error · UnsupportedOperationException

Unsupported type: ${type}

Error message

Unsupported type: ${type}

What it means

RowDataToAvroConverters.createConverter builds RowData→Avro converters per LogicalType. TIMESTAMP_WITH_LOCAL_TIME_ZONE fields are rejected with UnsupportedOperationException when legacyTimestampMapping is true, because the legacy Avro mapping cannot represent timestamptz on write.

Source

Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/formats/avro/RowDataToAvroConverters.java:223

                  } else {
                    // Iceberg: Added support for nanoseconds precision (FLINK-39251)
                    return instant.getEpochSecond() * 1_000_000_000L + instant.getNano();
                  }
                }
              };
        }
        break;
        // Iceberg: Added support for nanoseconds precision (FLINK-39251)
      case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
        final int ltzPrecision;
        if (type instanceof org.apache.flink.table.types.logical.LocalZonedTimestampType) {
          ltzPrecision =
              ((org.apache.flink.table.types.logical.LocalZonedTimestampType) type).getPrecision();
        } else {
          ltzPrecision = 3;
        }
        if (legacyTimestampMapping) {
          throw new UnsupportedOperationException("Unsupported type: " + type);
        } else {
          converter =
              new RowDataToAvroConverter() {
                private static final long serialVersionUID = 1L;

                @Override
                public Object convert(Schema schema, Object object) {
                  TimestampData timestampData = (TimestampData) object;
                  if (ltzPrecision <= 3) {
                    return timestampData.getMillisecond();
                  } else if (ltzPrecision <= 6) {
                    return timestampData.getMillisecond() * 1000L
                        + timestampData.getNanoOfMillisecond() / 1000;
                  } else {
                    // Iceberg: Added support for nanoseconds precision (FLINK-39251)
                    return timestampData.getMillisecond() * 1_000_000L
                        + timestampData.getNanoOfMillisecond();
                  }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Remove the legacy timestamp-mapping table property (use the modern int64 micros mapping) so timestamptz writes are allowed.
  2. Cast the timestamptz column to TIMESTAMP (without time zone) before writing if the legacy mapping must stay.
  3. Drop the timestamptz column from the written schema/projection.
  4. Use a writer/job configuration that doesn't enable legacyTimestampMapping.

Example fix

// before
DataFrame<RowData> out = in.map(row -> adjust(row)); // includes timestamptz col, legacy mapping on
// after
Cast to timestamp-without-time-zone first, or:
table.updateProperties().removeProperty("timestamp-without-time-zone-avro-mapping").commit();
Defensive patterns

Strategy: validation

Validate before calling

if (legacyTimestampMapping && rowType.getFields().stream().anyMatch(f -> f.getType() instanceof LocalZonedTimestampType)) {
  throw new IllegalArgumentException("Cannot write timestamptz with legacyTimestampMapping=true");
}

Type guard

boolean canWriteWithLegacy(LogicalType t) { return !(t instanceof LocalZonedTimestampType); }

Try / catch

try { writer.write(rowData); } catch (UnsupportedOperationException e) { // legacy mapping conflict: cast column to TimestampType or clear the mapping property }

Prevention

When it happens

Trigger: Writing Flink RowData (with a TIMESTAMP_WITH_LOCAL_TIME_ZONE column) out to Avro/Iceberg while the table's avro timestamp mapping is configured as legacy (e.g. 'timestamp-without-time-zone-avro-mapping' set to legacy-micros/legacy-millis).

Common situations: Pipelines configured with legacy mapping properties for backward compatibility that also carry timestamptz columns; copying legacy settings from older jobs into new timestamptz-enabled writes.

Related errors


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