prestodb/presto · error · PrestoException

HIVE_PARTITION_SCHEMA_MISMATCH

HIVE_PARTITION_SCHEMA_MISMATCH

Error message

Hive table (%s) is bucketed but partition (%s) is not bucketed

What it means

The table is bucketed (a real, non-virtual HiveBucketHandle exists) but one of its partitions has no bucketing property in its storage descriptor. Since bucket-aware reads require every partition to share the table's bucketing, Presto throws HIVE_PARTITION_SCHEMA_MISMATCH to flag the inconsistent partition.

Source

Thrown at presto-hive/src/main/java/com/facebook/presto/hive/HiveSplitManager.java:640

                    }
                }

                // Verify that the partition schema matches the table schema.
                // Either adding or dropping columns from the end of the table
                // without modifying existing partitions is allowed, but every
                // column that exists in both the table and partition must have
                // the same type.
                List<Column> tableColumns = table.getDataColumns();
                List<Column> partitionColumns = partition.getColumns();
                if ((tableColumns == null) || (partitionColumns == null)) {
                    throw new PrestoException(HIVE_INVALID_METADATA, format("Table '%s' or partition '%s' has null columns", tableName, partitionName));
                }
                TableToPartitionMapping tableToPartitionMapping = getTableToPartitionMapping(session, resolvedHiveStorageFormat, tableName, partitionName, tableColumns, partitionColumns);

                if (hiveBucketHandle.isPresent() && !hiveBucketHandle.get().isVirtuallyBucketed()) {
                    Optional<HiveBucketProperty> partitionBucketProperty = partition.getStorage().getBucketProperty();
                    if (!partitionBucketProperty.isPresent()) {
                        throw new PrestoException(HIVE_PARTITION_SCHEMA_MISMATCH, format(
                                "Hive table (%s) is bucketed but partition (%s) is not bucketed",
                                hivePartition.getTableName(),
                                hivePartition.getPartitionId().getPartitionName()));
                    }
                    int tableBucketCount = hiveBucketHandle.get().getTableBucketCount();
                    int partitionBucketCount = partitionBucketProperty.get().getBucketCount();
                    List<String> tableBucketColumns = hiveBucketHandle.get().getColumns().stream()
                            .map(HiveColumnHandle::getName)
                            .collect(toImmutableList());
                    List<String> partitionBucketColumns = partitionBucketProperty.get().getBucketedBy();
                    if (!tableBucketColumns.equals(partitionBucketColumns) || !isBucketCountCompatible(tableBucketCount, partitionBucketCount)) {
                        throw new PrestoException(HIVE_PARTITION_SCHEMA_MISMATCH, format(
                                "Hive table (%s) bucketing (columns=%s, buckets=%s) is not compatible with partition (%s) bucketing (columns=%s, buckets=%s)",
                                hivePartition.getTableName(),
                                tableBucketColumns,
                                tableBucketCount,
                                hivePartition.getPartitionId().getPartitionName(),
                                partitionBucketColumns,

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Rewrite/insert the offending partitions with the table's bucketing (INSERT OVERWRITE ... with matching bucket settings) so partitions become bucketed.
  2. Remove or repair the unbucketed partitions (ALTER TABLE DROP PARTITION) and re-add them correctly.
  3. If bucketing is not required, unbucket the table definition or disable bucket-aware execution (hive.bucket_execution=false) for these reads.
  4. Ensure all writers to the table honor the declared bucketing.

Example fix

// before
-- partition dt='2026-09-01' written unbucketed into bucketed table
// after
ALTER TABLE t DROP PARTITION (dt='2026-09-01');
INSERT OVERWRITE TABLE t PARTITION (dt='2026-09-01') SELECT ... ; -- with hive.enforce_bucketing / matching bucket count
Defensive patterns

Strategy: validation

Validate before calling

// verify partition bucketing before bucketed reads
Partition p = metastore.getPartition(db, table, values);
boolean bucketed = p != null && p.getStorage().getBucketProperty().isPresent();
if (!bucketed) { /* repair partition or disable bucket_execution */ }

Try / catch

catch (PrestoException e) { if (e.getErrorCode().getCode() == HIVE_PARTITION_SCHEMA_MISMATCH.toErrorCode().getCode()) { /* rerun with hive.bucket_execution=false or rewrite the partition */ } else throw e; }

Prevention

When it happens

Trigger: A query over a bucketed partitioned table reaches a partition whose StorageDescriptor lacks SerDe bucketing metadata (bucketCols/bucket count), during computePartitionMetadata.

Common situations: Partitions written/added by external jobs (Spark, custom writers) that ignored the table's bucketing; table altered to add bucketing after unbucketed partitions already existed; CTAS/insert overwriting with different settings.

Related errors


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