{"record":{"id":"12b6bf36b85559e0","repo":"apache/iceberg","slug":"unsupported-base-type-for-decimal-primitivetype","errorCode":null,"errorMessage":"Unsupported base type for decimal: ${primitiveTypeName}","messagePattern":"Unsupported base type for decimal: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/data/FlinkParquetWriters.java","lineNumber":231,"sourceCode":"      return Optional.of(strings(desc));\n    }\n\n    @Override\n    public Optional<ParquetValueWriter<?>> visit(DecimalLogicalTypeAnnotation decimal) {\n      ParquetValueWriter<DecimalData> writer;\n      switch (desc.getPrimitiveType().getPrimitiveTypeName()) {\n        case INT32:\n          writer = decimalAsInteger(desc, decimal.getPrecision(), decimal.getScale());\n          break;\n        case INT64:\n          writer = decimalAsLong(desc, decimal.getPrecision(), decimal.getScale());\n          break;\n        case BINARY:\n        case FIXED_LEN_BYTE_ARRAY:\n          writer = decimalAsFixed(desc, decimal.getPrecision(), decimal.getScale());\n          break;\n        default:\n          throw new UnsupportedOperationException(\n              \"Unsupported base type for decimal: \"\n                  + desc.getPrimitiveType().getPrimitiveTypeName());\n      }\n      return Optional.of(writer);\n    }\n\n    @Override\n    public Optional<ParquetValueWriter<?>> visit(DateLogicalTypeAnnotation dates) {\n      return Optional.of(ints(flinkType, desc));\n    }\n\n    @Override\n    public Optional<ParquetValueWriter<?>> visit(TimeLogicalTypeAnnotation times) {\n      Preconditions.checkArgument(\n          LogicalTypeAnnotation.TimeUnit.MICROS.equals(times.getUnit()),\n          \"Cannot write time in %s, only MICROS is supported\",\n          times.getUnit());\n      return Optional.of(timeMicros(desc));","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/data/FlinkParquetWriters.java#L213-L249","documentation":"LogicalTypeWriterBuilder.visit(DecimalLogicalTypeAnnotation) maps decimal columns to writers depending on the underlying physical type: INT32/INT64 for smaller decimals, BINARY/FIXED_LEN_BYTE_ARRAY for fixed decimals. Any other base type cannot store a decimal, so UnsupportedOperationException is thrown.","triggerScenarios":"A Parquet column annotated as decimal but physically stored as FLOAT, DOUBLE, INT96, or BOOLEAN - a combination the switch does not handle - triggering the default branch.","commonSituations":"Files written by non-conforming producers storing decimals on floating-point or legacy INT96 columns; hand-edited Parquet schemas; converting data from systems with loose decimal-to-physical-type mappings.","solutions":["Rewrite the source Parquet so decimal columns use a valid base type (int32, int64, binary, or fixed_len_byte_array).","Check the producing system's decimal-to-physical mapping and fix its configuration (e.g. spark.sql.parquet.writeLegacyFormat or equivalent).","Cast the column to a supported type (e.g. string or double) upstream if the decimal annotation is not required.","Verify the file with parquet-tools to confirm the actual physical type before assuming an Iceberg bug."],"exampleFix":"// before: parquet column: double col with DECIMAL(10,2) annotation\n// after: rewrite with a valid base type\n// Schema: required int64 col (DECIMAL(10,2))","handlingStrategy":"validation","validationCode":"for (Type f : parquetSchema.getFields()) {\n  if (f.isPrimitive()) {\n    LogicalTypeAnnotation ann = ((PrimitiveType) f).getLogicalTypeAnnotation();\n    PrimitiveTypeName base = ((PrimitiveType) f).getPrimitiveTypeName();\n    if (ann instanceof DecimalLogicalTypeAnnotation &&\n        !(base == INT32 || base == INT64 || base == BINARY || base == FIXED_LEN_BYTE_ARRAY)) {\n      throw new IllegalArgumentException(\"invalid decimal base: \" + base);\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  writer = ...build();\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().contains(\"Unsupported base type for decimal\")) {\n    // rewrite source data with valid decimal physical type\n  }\n}","preventionTips":["Fix the producing engine's decimal-to-physical-type configuration","Validate Parquet schemas at ingest time","Avoid hand-crafted Parquet schemas"],"tags":["flink","parquet","decimal","unsupported-type"],"backgroundTag":"invalid-argument-value","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}