{"record":{"id":"ee64d9c4b3a4bdd7","repo":"apache/iceberg","slug":"unsupported-base-type-for-decimal-primitive-get-ee64d9","errorCode":null,"errorMessage":"Unsupported base type for decimal: ${primitive.getPrimitiveTypeName()}","messagePattern":"Unsupported base type for decimal: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/data/SparkParquetReaders.java","lineNumber":271,"sourceCode":"          case DATE:\n          case INT_64:\n            return new UnboxedReader<>(desc);\n          case TIMESTAMP_MICROS:\n          case TIMESTAMP_MILLIS:\n            return ParquetValueReaders.timestamps(desc);\n          case DECIMAL:\n            DecimalLogicalTypeAnnotation decimal =\n                (DecimalLogicalTypeAnnotation) primitive.getLogicalTypeAnnotation();\n            switch (primitive.getPrimitiveTypeName()) {\n              case BINARY:\n              case FIXED_LEN_BYTE_ARRAY:\n                return new BinaryDecimalReader(desc, decimal.getScale());\n              case INT64:\n                return new LongDecimalReader(desc, decimal.getPrecision(), decimal.getScale());\n              case INT32:\n                return new IntegerDecimalReader(desc, decimal.getPrecision(), decimal.getScale());\n              default:\n                throw new UnsupportedOperationException(\n                    \"Unsupported base type for decimal: \" + primitive.getPrimitiveTypeName());\n            }\n          case BSON:\n            return new ParquetValueReaders.ByteArrayReader(desc);\n          default:\n            throw new UnsupportedOperationException(\n                \"Unsupported logical type: \" + primitive.getOriginalType());\n        }\n      }\n\n      switch (primitive.getPrimitiveTypeName()) {\n        case FIXED_LEN_BYTE_ARRAY:\n        case BINARY:\n          if (expected != null && expected.typeId() == TypeID.UUID) {\n            return new UUIDReader(desc);\n          }\n          return new ParquetValueReaders.ByteArrayReader(desc);\n        case INT32:","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/data/SparkParquetReaders.java#L253-L289","documentation":"When reading Parquet, decimal columns can be physically stored as FIXED_LEN_BYTE_ARRAY, BINARY, INT64, or INT32. SparkParquetReaders' primitive() method throws UnsupportedOperationException if a DECIMAL-annotated column uses any other base physical type, since no decimal reader exists for it.","triggerScenarios":"Reading a Parquet file whose decimal column is stored on an unexpected physical type (e.g. FLOAT/DOUBLE or INT96 with DECIMAL logical type) — typically from files written by non-conforming tools.","commonSituations":"Parquet files produced by legacy or buggy writers storing decimals with unusual physical representations; corrupted schema metadata; mixing files from different writers in one table.","solutions":["Rewrite the offending files with a standards-compliant writer (e.g. rewrite_data_files procedure).","Check the Parquet footer to confirm the decimal column's physical type.","Exclude or repair files written by the non-conforming producer before reading."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"ParquetMetadata meta = ParquetFileReader.readFooter(conf, path);\nfor (ColumnDescriptor cd : meta.getFileMetaData().getSchema().getColumns()) {\n  OriginalType ot = cd.getPrimitiveType().getOriginalType();\n  if (ot == OriginalType.DECIMAL) {\n    Primitive p = cd.getPrimitiveType().getPrimitiveTypeName();\n    if (p != FIXED_LEN_BYTE_ARRAY && p != BINARY && p != INT64 && p != INT32)\n      throw new IllegalStateException(\"bad decimal base: \" + cd.getPath());\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  icebergTable.newScan().toSpark().load();\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().startsWith(\"Unsupported base type for decimal\")) {\n    // rewrite offending files via rewrite_data_files\n  }\n}","preventionTips":["Write Parquet decimals only via conforming writers.","Validate external Parquet files before registering them with Iceberg (add_files checks)."],"tags":["parquet","spark","decimal","reader"],"backgroundTag":"incompatible-source-type","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"}