apache/iceberg · error · UnsupportedOperationException
Unsupported base type for decimal: %s
Error message
Unsupported base type for decimal: %s
What it means
In ParquetAvroWriter.primitive, a DECIMAL logical type whose underlying Parquet primitive is INT32/INT64 (non-BINARY/FIXED_LEN_BYTE_ARRAY) cannot be mapped to an Avro decimal writer. The library throws because the decimalAsFixed/decimalAsLong writers expect byte-backed storage. INT32/INT64-backed decimals are not supported by this Avro path.
Source
Thrown at parquet/src/main/java/org/apache/iceberg/parquet/ParquetAvroWriter.java:145
case TIME_MICROS:
case TIMESTAMP_MICROS:
return ParquetValueWriters.longs(desc);
case DECIMAL:
DecimalLogicalTypeAnnotation decimal =
(DecimalLogicalTypeAnnotation) primitive.getLogicalTypeAnnotation();
switch (primitive.getPrimitiveTypeName()) {
case INT32:
return ParquetValueWriters.decimalAsInteger(
desc, decimal.getPrecision(), decimal.getScale());
case INT64:
return ParquetValueWriters.decimalAsLong(
desc, decimal.getPrecision(), decimal.getScale());
case BINARY:
case FIXED_LEN_BYTE_ARRAY:
return ParquetValueWriters.decimalAsFixed(
desc, decimal.getPrecision(), decimal.getScale());
default:
throw new UnsupportedOperationException(
"Unsupported base type for decimal: " + primitive.getPrimitiveTypeName());
}
case BSON:
return ParquetValueWriters.byteBuffers(desc);
default:
throw new UnsupportedOperationException(
"Unsupported logical type: " + primitive.getOriginalType());
}
}
switch (primitive.getPrimitiveTypeName()) {
case FIXED_LEN_BYTE_ARRAY:
return new FixedWriter(desc);
case BINARY:
return ParquetValueWriters.byteBuffers(desc);
case BOOLEAN:
return ParquetValueWriters.booleans(desc);
case INT32:View on GitHub (pinned to 86d9c8fc54)
Solutions
- Rewrite the data so the decimal is stored as BINARY or FIXED_LEN_BYTE_ARRAY physical type
- Use a writer that handles INT32/INT64-backed decimals (non-Avro Iceberg Parquet writer)
- Convert the column to a string or double before writing via the Avro path
Example fix
// before
throw new UnsupportedOperationException("Unsupported base type for decimal: " + primitive.getPrimitiveTypeName());
// after (engine-side fix): force binary-backed decimal
Types.DecimalType.of(precision, scale) written via FIXED_LEN_BYTE_ARRAY storage Defensive patterns
Strategy: validation
Validate before calling
boolean badDecimal = schema.columns().stream().anyMatch(c ->
c.type() instanceof Types.DecimalType && columnPhysical(c) != FIXED_LEN_BYTE_ARRAY && columnPhysical(c) != BINARY);
if (badDecimal) throw new IllegalArgumentException("Decimal must be BINARY/FIXED_LEN_BYTE_ARRAY backed"); Try / catch
try { writer.write(record); } catch (UnsupportedOperationException e) { if (e.getMessage().startsWith("Unsupported base type for decimal")) { /* rewrite decimal column as binary-backed */ } else { throw e; } } Prevention
- Use FIXED_LEN_BYTE_ARRAY-backed decimals (the common default)
- Avoid INT32/INT64-backed decimal Parquet files on the Avro write path
- Validate physical backing of decimal columns before writing
When it happens
Trigger: Writing a Parquet column annotated DECIMAL with physical type INT32 or INT64 (or any primitive other than BINARY/FIXED_LEN_BYTE_ARRAY) through ParquetAvroWriter.primitive.
Common situations: Parquet files produced by other engines (e.g., Spark/Hive writing decimals as INT32/INT64 per newer spec revisions) are written via the Avro writer path; schema evolution changed decimal backing storage.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Unsupported base type for decimal: ${primitiveTypeName}
- Unsupported base type for decimal: ${desc.getPrimitiveType()
- Avro writer does not support variant types
- Unsupported logical type: %s
- Unsupported base type for decimal:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/aa7a7d5ac3a88d06.
Report an issue: GitHub.