apache/iceberg · error · UnsupportedOperationException

Unsupported type for Parquet

Error message

Unsupported type for Parquet: ${primitive}

What it means

TypeToMessageType.primitive maps Iceberg primitive types to Parquet PrimitiveTypes with logical type annotations. The switch covers all known primitives; hitting default means an Iceberg primitive type has no Parquet mapping in this version, so conversion aborts with UnsupportedOperationException naming the type.

Solutions

  1. Read the type named in the message and confirm it is a supported Iceberg primitive for Parquet writes.
  2. Upgrade iceberg-parquet (and Iceberg generally) to a version that maps the type.
  3. Remove or remap the unsupported column (e.g. store as string/binary) if upgrading is not possible.

Example fix

// before
Schema schema = new Schema(required(1, "v", Types.VariantType.get())); // older writer
typeToMessageType.convert(schema.asStruct());
// after
// upgrade to a version where VariantType maps to Parquet variant, or:
Schema schema = new Schema(required(1, "v", Types.StringType.get()));
Defensive patterns

Strategy: validation

Validate before calling

Set<Class<?>> unsupported = schema.columns().stream()
    .map(f -> f.type().getClass())
    .filter(c -> !SUPPORTED_PARQUET_PRIMITIVES.contains(c))
    .collect(Collectors.toSet());
if (!unsupported.isEmpty()) { throw new IllegalArgumentException("Unsupported for Parquet: " + unsupported); }

Type guard

boolean supportedForParquet(Type t) { return t.isPrimitiveType() && KNOWN_MAPPINGS.containsKey(t.asPrimitiveType().typeId()); }

Try / catch

try {
  schemaDataType = typeToMessageType.convert(schema.asStruct());
} catch (UnsupportedOperationException e) {
  LOG.error("Column type unsupported by this Iceberg version: {}", e.getMessage());
  throw e;
}

Prevention

When it happens

Trigger: Calling TypeToMessageType.primitive() (via field()) with an Iceberg primitive type not handled by the switch — typically a newly introduced type (e.g. a variant/geography/unknown-nanosecond type) on an older converter, or a custom primitive type.

Common situations: Writing tables whose schema uses a type added in a newer Iceberg spec while the parquet module is older; custom Type implementations; unknown types deserialized from foreign metadata.

Related errors


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

Appendix: source

Thrown at parquet/src/main/java/org/apache/iceberg/parquet/TypeToMessageType.java:304

      case GEOMETRY:
        GeometryType geometry = (GeometryType) primitive;
        return Types.primitive(BINARY, repetition)
            .as(LogicalTypeAnnotation.geometryType(geometry.crs()))
            .id(id)
            .named(name);

      case GEOGRAPHY:
        GeographyType geography = (GeographyType) primitive;
        return Types.primitive(BINARY, repetition)
            .as(
                LogicalTypeAnnotation.geographyType(
                    geography.crs(), toParquet(geography.algorithm())))
            .id(id)
            .named(name);

      default:
        throw new UnsupportedOperationException("Unsupported type for Parquet: " + primitive);
    }
  }

  private static EdgeInterpolationAlgorithm toParquet(EdgeAlgorithm algorithm) {
    // Iceberg and Parquet use the same algorithm names (SPHERICAL, VINCENTY, THOMAS, ANDOYER,
    // KARNEY) so the algorithm is mapped by name
    return EdgeInterpolationAlgorithm.valueOf(algorithm.name());
  }

  private static LogicalTypeAnnotation decimalAnnotation(int precision, int scale) {
    return LogicalTypeAnnotation.decimalType(scale, precision);
  }
}

View on GitHub (pinned to 86d9c8fc54)