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
- Add bucketed_by and bucket_count alongside sorted_by in the WITH clause.
- Remove the sorted_by property if you don't need bucketed, sorted tables.
- 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
- Always pair sorted_by with bucketed_by + bucket_count
- Validate DDL properties in your schema-management tooling
- Run SHOW CREATE TABLE on reference tables to copy correct clause sets
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
- INVALID_TABLE_PROPERTY
- Invalid value [%s]. Valid values: %s
- HIVE_INVALID_METADATA
- GENERIC_USER_ERROR
- ALREADY_EXISTS
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/34d801a056960b0b.
Report an issue: GitHub.