apache/iceberg · error · java.lang.UnsupportedOperationException

Unsupported NullType.

Error message

Unsupported NullType.

What it means

Type-visitor guard in FlinkTypeVisitor: the Flink NullType has no meaningful Iceberg representation in this conversion path (unlike the schema conversion that can map it to void/unknown), so visiting it during read/write planning fails. It indicates the Flink schema contains an untyped null column.

Solutions

  1. Add an explicit CAST to the NULL expression (e.g. CAST(NULL AS STRING)) in the SQL
  2. Declare the column type explicitly in the sink DDL instead of relying on inference
  3. Replace NullType columns with a concrete nullable primitive type in the RowType

Example fix

// before
SELECT NULL AS flag -- NullType column -> throws
// after
SELECT CAST(NULL AS STRING) AS flag
Defensive patterns

Strategy: validation

Validate before calling

List<String> nullCols = rowType.getFields().stream()
  .filter(f -> f.getType() instanceof NullType)
  .map(RowType.RowField::getName)
  .collect(Collectors.toList());
if (!nullCols.isEmpty()) throw new IllegalArgumentException("Cast NULL columns: " + nullCols);

Type guard

boolean isSupported(LogicalType t) {
  return !(t instanceof NullType);
}

Prevention

When it happens

Trigger: Converting a Flink RowType that includes NullType columns, commonly produced by SELECT NULL, VALUES with all NULLs, or UDFs returning NullType.

Common situations: Insert pipelines that emit NULL literals without casts; dynamic SQL generating untyped NULL columns that end up in an Iceberg sink schema.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/FlinkTypeVisitor.java:63

  @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
  public T visit(SymbolType<?> symbolType) {
    throw new UnsupportedOperationException("Unsupported SymbolType.");
  }

  @Override
  public T visit(LogicalType other) {
    throw new UnsupportedOperationException("Unsupported type: " + other);
  }
}

View on GitHub (pinned to 86d9c8fc54)