prestodb/presto · error · PrestoException

INVALID_TABLE_PROPERTY

INVALID_TABLE_PROPERTY

Error message

%s may be specified only when %s is specified

What it means

HiveTableProperties.getBucketProperty validates CREATE TABLE bucketing properties. SORTED_BY (sorted_by) is only meaningful together with bucketing, so specifying sorted_by without bucketed_by/bucket_count raises INVALID_TABLE_PROPERTY.

Source

Thrown at presto-hive/src/main/java/com/facebook/presto/hive/HiveTableProperties.java:221

    {
        return (HiveStorageFormat) tableProperties.get(STORAGE_FORMAT_PROPERTY);
    }

    @SuppressWarnings("unchecked")
    public static List<String> getPartitionedBy(Map<String, Object> tableProperties)
    {
        List<String> partitionedBy = (List<String>) tableProperties.get(PARTITIONED_BY_PROPERTY);
        return partitionedBy == null ? ImmutableList.of() : ImmutableList.copyOf(partitionedBy);
    }

    public static Optional<HiveBucketProperty> getBucketProperty(Map<String, Object> tableProperties)
    {
        List<String> bucketedBy = getBucketedBy(tableProperties);
        List<SortingColumn> sortedBy = getSortedBy(tableProperties);
        int bucketCount = (Integer) tableProperties.get(BUCKET_COUNT_PROPERTY);
        if ((bucketedBy.isEmpty()) && (bucketCount == 0)) {
            if (!sortedBy.isEmpty()) {
                throw new PrestoException(INVALID_TABLE_PROPERTY, format("%s may be specified only when %s is specified", SORTED_BY_PROPERTY, BUCKETED_BY_PROPERTY));
            }
            return Optional.empty();
        }
        if (bucketCount < 0) {
            throw new PrestoException(INVALID_TABLE_PROPERTY, format("%s must be greater than zero", BUCKET_COUNT_PROPERTY));
        }
        if (bucketCount > 1_000_000) {
            throw new PrestoException(INVALID_TABLE_PROPERTY, format("%s should be no more than 1000000", BUCKET_COUNT_PROPERTY));
        }
        if (bucketedBy.isEmpty() || bucketCount == 0) {
            throw new PrestoException(INVALID_TABLE_PROPERTY, format("%s and %s must be specified together", BUCKETED_BY_PROPERTY, BUCKET_COUNT_PROPERTY));
        }
        return Optional.of(new HiveBucketProperty(bucketedBy, bucketCount, sortedBy, HIVE_COMPATIBLE, Optional.empty()));
    }

    @SuppressWarnings("unchecked")
    private static List<String> getBucketedBy(Map<String, Object> tableProperties)
    {

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Add bucketed_by and bucket_count alongside sorted_by in the WITH clause.
  2. Remove the sorted_by property if you don't need bucketed, sorted tables.
  3. Note: bucket_count == 0 with bucketed_by also counts as 'not specified', so ensure both are present and positive.

Example fix

// before
CREATE TABLE t (a bigint) WITH (sorted_by = ARRAY['a ASC']);
// after
CREATE TABLE t (a bigint) WITH (bucketed_by = ARRAY['a'], bucket_count = 32, sorted_by = ARRAY['a ASC']);
Defensive patterns

Strategy: validation

Validate before calling

// validate DDL properties before CREATE TABLE
Map<String,Object> props = parseWithClause(withClause);
boolean hasSorted = props.containsKey("sorted_by");
boolean hasBuckets = props.containsKey("bucketed_by") && props.containsKey("bucket_count");
if (hasSorted && !hasBuckets) throw new IllegalArgumentException("sorted_by requires bucketed_by and bucket_count");

Try / catch

try { createTable(ddl); } catch (PrestoException e) {
    if (INVALID_TABLE_PROPERTY.toErrorCode().getCode() == e.getErrorCode().getCode()) {
        throw new IllegalArgumentException("Fix bucketing properties: " + e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: CREATE TABLE ... WITH (sorted_by = ARRAY['col ASC']) without bucketed_by or bucket_count (or when both are absent/empty), as seen in getBucketProperty when bucketedBy.isEmpty() && bucketCount == 0 but sortedBy is non-empty.

Common situations: Typos or misunderstanding that sorted_by requires bucketing; copying sorted_by clause from a bucketed table while dropping bucket clauses; connectors' schema generators emitting sorted_by alone.

Related errors


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