prestodb/presto · error · ParquetDecodingException
Unable to read BINARY type decimal of size
Error message
Unable to read BINARY type decimal of size
What it means
BinaryShortDecimalPlainValuesDecoder reads PLAIN-encoded BINARY values and converts each to a short decimal. Any value whose binary length exceeds 8 bytes cannot fit a short decimal unscaled value, so readNext throws a ParquetDecodingException with the offending size. This guards against silently truncating large decimals.
Source
Thrown at presto-parquet/src/main/java/com/facebook/presto/parquet/batchreader/decoders/plain/BinaryShortDecimalPlainValuesDecoder.java:51
{
requireNonNull(byteBuffer, "buffer is null");
delegate = new BinaryPlainValuesDecoder(byteBuffer, bufferOffset, length);
}
@Override
public void readNext(long[] values, int offset, int length)
{
ValueBuffer valueBuffer = delegate.readNext(length);
int bufferSize = valueBuffer.getBufferSize();
byte[] byteBuffer = new byte[bufferSize];
int[] offsets = new int[length + 1];
delegate.readIntoBuffer(byteBuffer, 0, offsets, 0, valueBuffer);
for (int i = 0; i < length; i++) {
int positionOffset = offsets[i];
int positionLength = offsets[i + 1] - positionOffset;
if (positionLength > 8) {
throw new ParquetDecodingException("Unable to read BINARY type decimal of size " + positionLength + " as a short decimal");
}
values[offset + i] = getShortDecimalValue(byteBuffer, positionOffset, positionLength);
}
}
@Override
public void skip(int length)
{
checkArgument(length >= 0, "invalid length %s", length);
delegate.skip(length);
}
@Override
public long getRetainedSizeInBytes()
{
return INSTANCE_SIZE;
}View on GitHub (pinned to 55bb57d202)
Solutions
- Check the file's DECIMAL precision with parquet-tools and align the table schema/read type to it
- Cast or read as a long decimal (precision > 18) instead of a short decimal
- Rewrite the data with the correct short-decimal precision (<= 18) if values genuinely fit
- Fail fast at write time by validating unscaled values fit in 8 bytes before encoding
Example fix
// before: DECIMAL(30,5) file read as short decimal -> exception // after: recreate table with matching precision // CREATE TABLE t (col DECIMAL(30,5)) ... or CAST to DECIMAL(30,5) on read
Defensive patterns
Strategy: validation
Validate before calling
// Before mapping the column to a short decimal, check its declared precision: // if (precision > 18) use long decimal path // parquet-tools schema file.parquet | grep 'DECIMAL'
Type guard
boolean fitsShortDecimal(int declaredPrecision) { return declaredPrecision <= 18; } Try / catch
try {
decoder.readNext(length);
} catch (ParquetDecodingException e) {
if (e.getMessage().contains("as a short decimal")) {
// switch to a long-decimal decoder for this column
}
throw e;
} Prevention
- Match table schema precision to the file's DECIMAL annotation
- Avoid ALTER TABLE ... shrinking precision on external Parquet tables
- Audit external table files with parquet-tools at registration
- Cast explicitly to a wider decimal when values may exceed 18 digits
When it happens
Trigger: readNext() over PLAIN-encoded binary decimal data where offsets[i+1]-offsets[i] > 8 for any value.
Common situations: DECIMAL columns written with precision > 18 (16-byte binary) but read/declared as short decimal; schema evolution where the table was altered to a smaller precision; external tables pointing at files with mismatched decimal annotations.
Related errors
- Corrupted Parquet file: extra %d values to be consumed when
- Corrupted Parquet file: extra %d values to be consumed when
- Unable to read BINARY type decimal of size
- Unable to read BINARY type decimal of size
- Unsupported Parquet encoding:
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/98d7b0b9074277c6.
Report an issue: GitHub.