prestodb/presto · error · PrestoException

GENERIC_INTERNAL_ERROR

GENERIC_INTERNAL_ERROR

Error message

Invalid partition type 

What it means

deserializeIcebergValue handles only Presto primitive types (boolean, integer, bigint, real, double, timestamp, time, date, varchar, varbinary, decimal). If the partition key's Presto type is not one of these, it falls through and throws PrestoException(GENERIC_INTERNAL_ERROR, "Invalid partition type ..."), because Iceberg tables are not expected to partition on non-primitive-type columns. Hitting it means the connector encountered a partition key type it believes cannot exist.

Source

Thrown at presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergUtil.java:961

            }
            if (isShortDecimal(type) || isLongDecimal(type)) {
                DecimalType decimalType = (DecimalType) type;
                BigDecimal decimal = new BigDecimal(valueString);
                decimal = decimal.setScale(decimalType.getScale(), BigDecimal.ROUND_UNNECESSARY);
                checkArgument(decimal.precision() <= decimalType.getPrecision());
                BigInteger unscaledValue = decimal.unscaledValue();
                return isShortDecimal(type) ? unscaledValue.longValue() : Decimals.encodeUnscaledValue(unscaledValue);
            }
        }
        catch (IllegalArgumentException e) {
            throw new PrestoException(ICEBERG_INVALID_PARTITION_VALUE, format(
                    "Invalid partition value '%s' for %s partition key: %s",
                    valueString,
                    type.getDisplayName(),
                    name));
        }
        // Iceberg tables don't partition by non-primitive-type columns.
        throw new PrestoException(GENERIC_INTERNAL_ERROR, "Invalid partition type " + type.toString());
    }

    public static Domain createDomainFromIcebergPartitionValue(
            Object value,
            org.apache.iceberg.types.Type icebergType,
            Type prestoType)
    {
        if (value == null) {
            return onlyNull(prestoType);
        }

        switch (icebergType.typeId()) {
            case INTEGER:
            case DATE:
                return singleValue(prestoType, ((Integer) value).longValue());
            case LONG:
            case BOOLEAN:
                return singleValue(prestoType, value);

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Inspect the table's Iceberg partition spec to identify the non-primitive partition field and rewrite the table so partition keys are primitive columns
  2. Check for schema/partition-spec edits by other engines; revert to a spec with only primitive partition keys
  3. If this appears with a valid spec, it is a connector type-mapping bug — report it with the partition spec and schema to the Presto maintainers
  4. As a workaround, drop/replace the offending partition field in the spec (Iceberg partition fields are advisory for reads; repartition the data)

Example fix

// before: partition spec on a struct column
PartitionSpec spec = PartitionSpec.builderFor(schema).identity("nested_struct_col").build();
// after: partition on a primitive column extracted from the data
PartitionSpec spec = PartitionSpec.builderFor(schema).identity("event_date").build();
Defensive patterns

Strategy: validation

Validate before calling

// Ensure all partition fields map to primitive types before querying
java.util.Set<String> PRIMITIVES = java.util.Set.of("boolean","integer","long","float","double","date","time","timestamp","string","uuid","decimal","fixed","binary");
boolean hasOnlyPrimitivePartitionFields(org.apache.iceberg.Table table) {
    return table.spec().fields().stream()
        .allMatch(f -> PRIMITIVES.contains(f.transform().getResultType(
            table.schema().findType(f.sourceId())).typeId().toString().toLowerCase()));
}

Type guard

boolean isPrimitivePartitionType(org.apache.iceberg.types.Type t) {
    switch (t.typeId()) {
        case BOOLEAN: case INTEGER: case LONG: case FLOAT: case DOUBLE:
        case DATE: case TIME: case TIMESTAMP: case STRING: case UUID:
        case DECIMAL: case FIXED: case BINARY:
            return true;
        default:
            return false;
    }
}

Try / catch

try {
    session.execute(query);
} catch (QueryFailedException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Invalid partition type")) {
        // inspect/fix the partition spec; this is not retryable
    } else throw e;
}

Prevention

When it happens

Trigger: Reading Iceberg partitions where a partition field maps to a non-primitive Presto type (e.g. map, array, struct, row, or any type not matched in the if-chain in deserializeIcebergValue). Typically only occurs with corrupted/hand-edited metadata or an engine that wrote an unsupported partition spec.

Common situations: External writers partitioning on complex columns contrary to the Iceberg spec assumption; connector type mapping mismatches after schema evolution; hand-modified partition specs in metadata JSON.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/093826dc9b01f930. Report an issue: GitHub.