prestodb/presto · error · IllegalArgumentException

Writing to skewed table/partition is not supported

Error message

Writing to skewed table/partition is not supported

What it means

makeStorageDescriptor builds the Metastore StorageDescriptor when writing table/partition metadata. Presto's write path does not support skewed table layouts, so if the target Storage has isSkewed() set, it throws IllegalArgumentException. Skewed tables (rows for certain values stored in separate directories) can be read but not created/written through this connector.

Source

Thrown at presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/thrift/ThriftMetastoreUtil.java:701

    public static void fromMetastoreApiStorageDescriptor(StorageDescriptor storageDescriptor, Storage.Builder builder, String tablePartitionName)
    {
        SerDeInfo serdeInfo = storageDescriptor.getSerdeInfo();
        if (serdeInfo == null) {
            throw new PrestoException(HIVE_INVALID_METADATA, "Table storage descriptor is missing SerDe info");
        }

        builder.setStorageFormat(StorageFormat.createNullable(serdeInfo.getSerializationLib(), storageDescriptor.getInputFormat(), storageDescriptor.getOutputFormat()))
                .setLocation(nullToEmpty(storageDescriptor.getLocation()))
                .setBucketProperty(HiveBucketProperty.fromStorageDescriptor(storageDescriptor, tablePartitionName))
                .setSkewed(storageDescriptor.isSetSkewedInfo() && storageDescriptor.getSkewedInfo().isSetSkewedColNames() && !storageDescriptor.getSkewedInfo().getSkewedColNames().isEmpty())
                .setSerdeParameters(serdeInfo.getParameters() == null ? ImmutableMap.of() : serdeInfo.getParameters())
                .setParameters(storageDescriptor.getParameters() == null ? ImmutableMap.of() : storageDescriptor.getParameters());
    }

    private static StorageDescriptor makeStorageDescriptor(String tableName, List<Column> columns, Storage storage, ColumnConverter columnConverter)
    {
        if (storage.isSkewed()) {
            throw new IllegalArgumentException("Writing to skewed table/partition is not supported");
        }
        SerDeInfo serdeInfo = new SerDeInfo();
        serdeInfo.setName(tableName);
        serdeInfo.setSerializationLib(storage.getStorageFormat().getSerDeNullable());
        serdeInfo.setParameters(storage.getSerdeParameters());

        StorageDescriptor sd = new StorageDescriptor();
        sd.setLocation(emptyToNull(storage.getLocation()));
        sd.setCols(columns.stream()
                .map(col -> ThriftMetastoreUtil.toMetastoreApiFieldSchema(col, columnConverter))
                .collect(toList()));
        sd.setSerdeInfo(serdeInfo);
        sd.setInputFormat(storage.getStorageFormat().getInputFormatNullable());
        sd.setOutputFormat(storage.getStorageFormat().getOutputFormatNullable());
        sd.setParameters(storage.getParameters());

        Optional<HiveBucketProperty> bucketProperty = storage.getBucketProperty();
        if (bucketProperty.isPresent()) {

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Remove the skew specification: recreate the table without SKEWED BY and write to that
  2. Use Hive to write to skewed tables; keep Presto reads only
  3. If skew definition is unnecessary, ALTER TABLE ... SET SKEWED LOCATION / unset skewed properties in Hive before writing via Presto

Example fix

-- before
CREATE TABLE t (a int) SKEWED BY (a) ON ((1)) STORED AS DIRECTORIES;
-- after
CREATE TABLE t (a int) STORED AS PARQUET; -- no SKEWED BY
Defensive patterns

Strategy: validation

Validate before calling

// check before writing via Presto
Table hiveTable = metastore.getTable(db, table).orElseThrow(...);
boolean skewed = hiveTable.getParameters().containsKey("SKEWED")
    || (hiveTable.getSd() != null && hiveTable.getSd().isSetSkewedInfo());
if (skewed) {
    throw new PrestoException(NOT_SUPPORTED, "Route writes to " + table + " through Hive; skewed tables unsupported");
}

Type guard

boolean isSkewedStorage(Storage storage) {
    return storage != null && storage.isSkewed();
}

Try / catch

try {
    insert/ctas into target table;
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("skewed table/partition")) {
        throw new PrestoException(NOT_SUPPORTED,
            "Target is a skewed Hive table; write via Hive or recreate without SKEWED BY", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Attempting CREATE TABLE ... SKEWED BY (...) or writing/altering into a table/partition that Presto metadata marked as skewed — makeStorageDescriptor is called on every createTable/finishInsert/commit path.

Common situations: Migrating a skewed Hive table to Presto and trying to write to it; CTAS or INSERT into a table whose source definition was skewed; schema copy tools that clone skewed properties.

Related errors


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