{"record":{"id":"023c23b737b3c3f6","repo":"apache/iceberg","slug":"invalid-primitive-type-for-decimal","errorCode":null,"errorMessage":"Invalid primitive type for decimal: ","messagePattern":"Invalid primitive type for decimal: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/avro/ValueReaders.java","lineNumber":142,"sourceCode":"    return BytesReader.INSTANCE;\n  }\n\n  public static ValueReader<ByteBuffer> byteBuffers() {\n    return ByteBufferReader.INSTANCE;\n  }\n\n  public static ValueReader<BigDecimal> decimal(ValueReader<byte[]> unscaledReader, int scale) {\n    return new DecimalReader(unscaledReader, scale);\n  }\n\n  public static ValueReader<byte[]> decimalBytesReader(Schema schema) {\n    switch (schema.getType()) {\n      case FIXED:\n        return ValueReaders.fixed(schema.getFixedSize());\n      case BYTES:\n        return ValueReaders.bytes();\n      default:\n        throw new IllegalArgumentException(\n            \"Invalid primitive type for decimal: \" + schema.getType());\n    }\n  }\n\n  public static ValueReader<Variant> variants() {\n    return VariantReader.INSTANCE;\n  }\n\n  public static ValueReader<Object> union(List<ValueReader<?>> readers) {\n    return new UnionReader(readers);\n  }\n\n  public static ValueReader<Long> positions() {\n    return new PositionReader();\n  }\n\n  public static <T> ValueReader<Collection<T>> array(ValueReader<T> elementReader) {\n    return new ArrayReader<>(elementReader);","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/avro/ValueReaders.java#L124-L160","documentation":"ValueReaders.decimalBytesReader supports decimals stored as Avro FIXED or BYTES; any other Avro primitive type cannot carry decimal bytes and triggers this IllegalArgumentException. It guards the schema used for the logical decimal type.","triggerScenarios":"Reading an Avro schema where a decimal logical type is attached to an unexpected primitive (e.g. STRING or INT) instead of FIXED (with fixed-size) or BYTES.","commonSituations":"Hand-written or tool-rewritten Avro schemas losing the underlying primitive type; foreign writers serializing decimals incorrectly; schema translation bugs.","solutions":["Fix the Avro schema so the decimal field's type is bytes with logicalType 'decimal' or fixed with the required byte size","Compute the required bytes with TypeUtil.decimalRequiredBytes(precision) when using fixed","Rewrite the file with a writer that follows the Iceberg Avro encoding for decimals"],"exampleFix":"// before\n{\"type\": \"string\", \"logicalType\": \"decimal\", \"precision\": 10, \"scale\": 2}\n// after\n{\"type\": \"bytes\", \"logicalType\": \"decimal\", \"precision\": 10, \"scale\": 2}","handlingStrategy":"validation","validationCode":"Schema.Field f = schema.getField(\"amount\");\nSchema type = f.schema().getTypes().size() > 1 ? f.schema().getTypes().get(1) : f.schema();\nboolean ok = type.getType() == Schema.Type.BYTES || type.getType() == Schema.Type.FIXED;","typeGuard":"boolean decimalSchemaOk(Schema s) { return s.getLogicalType() instanceof LogicalTypes.Decimal && (s.getType() == Schema.Type.BYTES || s.getType() == Schema.Type.FIXED); }","tryCatchPattern":"try { ValueReader<BigDecimal> r = ValueReaders.decimals(schema); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith(\"Invalid primitive type for decimal\")) { /* fix schema */ } else throw e; }","preventionTips":["Verify decimal fields are bytes/fixed after any schema round-trip through external tools","Match fixed size to TypeUtil.decimalRequiredBytes(precision)","Regenerate schemas from the Iceberg schema rather than editing JSON by hand"],"tags":["avro","decimal","schema"],"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"}