prestodb/presto · error · PrestoException
HIVE_UNSUPPORTED_ENCRYPTION_OPERATION
HIVE_UNSUPPORTED_ENCRYPTION_OPERATION
Error message
Creating an encrypted table without partitions is not supported. Use CREATE TABLE AS SELECT to create an encrypted table without partitions
What it means
Presto only supports encrypted Hive tables when they are partitioned; encryption metadata is applied per-partition. When getTableEncryptionPropertiesFromTableProperties returns encryption properties and the target table has no partitioned_by columns, CreateTable throws HIVE_UNSUPPORTED_ENCRYPTION_OPERATION and directs users to CTAS.
Source
Thrown at presto-hive/src/main/java/com/facebook/presto/hive/HiveMetadata.java:1084
{
SchemaTableName schemaTableName = tableMetadata.getTable();
String schemaName = schemaTableName.getSchemaName();
String tableName = schemaTableName.getTableName();
List<String> partitionedBy = getPartitionedBy(tableMetadata.getProperties());
Optional<HiveBucketProperty> bucketProperty = getBucketProperty(tableMetadata.getProperties());
if (bucketProperty.isPresent() && getAvroSchemaUrl(tableMetadata.getProperties()) != null) {
throw new PrestoException(NOT_SUPPORTED, "Bucketing columns not supported when Avro schema url is set");
}
List<HiveColumnHandle> columnHandles = getColumnHandles(tableMetadata, ImmutableSet.copyOf(partitionedBy), typeTranslator);
HiveStorageFormat hiveStorageFormat = getHiveStorageFormat(tableMetadata.getProperties());
List<SortingColumn> preferredOrderingColumns = getPreferredOrderingColumns(tableMetadata.getProperties());
Optional<TableEncryptionProperties> tableEncryptionProperties = getTableEncryptionPropertiesFromTableProperties(tableMetadata, hiveStorageFormat, partitionedBy);
if (tableEncryptionProperties.isPresent() && partitionedBy.isEmpty()) {
throw new PrestoException(HIVE_UNSUPPORTED_ENCRYPTION_OPERATION, "Creating an encrypted table without partitions is not supported. Use CREATE TABLE AS SELECT to " +
"create an encrypted table without partitions");
}
validateColumns(hiveStorageFormat, columnHandles);
MetastoreContext metastoreContext = getMetastoreContext(session);
Map<String, HiveColumnHandle> columnHandlesByName = Maps.uniqueIndex(columnHandles, HiveColumnHandle::getName);
List<Column> partitionColumns = partitionedBy.stream()
.map(columnHandlesByName::get)
.map(columnHandle -> columnHandleToColumn(metastoreContext, columnHandle))
.collect(toList());
checkPartitionTypesSupported(partitionColumns);
Path targetPath;
if (tableType.equals(EXTERNAL_TABLE)) {
if (!createsOfNonManagedTablesEnabled) {
throw new PrestoException(NOT_SUPPORTED, "Cannot create non-managed Hive table");View on GitHub (pinned to 55bb57d202)
Solutions
- Use CREATE TABLE AS SELECT (CTAS) instead of CREATE TABLE ... AS the message suggests, since unpartitioned encrypted tables are only supported that way
- Add partitioned_by columns to the CREATE TABLE statement so the table is partitioned
- Drop the encryption properties if encryption is not actually required
Example fix
// before CREATE TABLE t WITH (format='ORC', encrypted=true, encryption_algorithm='AES_GCM_CTR', encryption_key_provider='...') AS SELECT ... // after CREATE TABLE t WITH (format='ORC', partitioned_by=ARRAY['ds']) AS SELECT *, '2026-09-04' AS ds FROM src -- or use plain CTAS without partition clause CREATE TABLE t WITH (format='ORC') AS SELECT * FROM src;
Defensive patterns
Strategy: validation
Validate before calling
// before CREATE TABLE with encryption
boolean encrypted = properties.containsKey("encrypted") || properties.containsKey("encryption_key_provider");
List<String> partitionedBy = (List<String>) properties.getOrDefault("partitioned_by", List.of());
if (encrypted && partitionedBy.isEmpty()) {
throw new IllegalArgumentException("Unpartitioned encrypted tables require CREATE TABLE AS SELECT");
} Type guard
boolean isUnpartitionedEncryptedCreate(Map<String,Object> properties) {
List<?> partitionedBy = (List<?>) properties.get("partitioned_by");
return properties.containsKey("encrypted")
&& (partitionedBy == null || partitionedBy.isEmpty());
} Try / catch
try {
connector.createTable(session, columns, properties);
} catch (PrestoException e) {
if (e.getMessage() != null && e.getMessage().contains("encrypted table without partitions")) {
// fall back to CTAS: connector.createTableAsSelect with encryption properties
} else { throw e; }
} Prevention
- Always use CTAS when creating unpartitioned encrypted tables
- Add partitioned_by columns if a plain CREATE TABLE with encryption is needed
- Keep encryption properties out of DDL templates unless encryption is truly required
When it happens
Trigger: CREATE TABLE ... WITH (encrypted=..., encryption_algorithm=..., encryption_key_provider=...) without a partitioned_by property — i.e. an unpartitioned encrypted table created via CREATE TABLE (not CREATE TABLE AS SELECT).
Common situations: Following Hive encryption examples without partitioning; converting existing encrypted Hive scripts to Presto DDL; misunderstanding that CTAS is the required path for unpartitioned encrypted tables.
Related errors
- GENERIC_INTERNAL_ERROR
- HIVE_INVALID_ENCRYPTION_METADATA
- HIVE_INVALID_ENCRYPTION_METADATA
- HIVE_INVALID_ENCRYPTION_METADATA
- NOT_SUPPORTED
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/5eb025d65b9132cd.
Report an issue: GitHub.