prestodb/presto · error · PrestoException
HIVE_UNSUPPORTED_FORMAT
HIVE_UNSUPPORTED_FORMAT
Error message
Table StorageDescriptor is null for table %s.%s (%s)
What it means
When converting a Glue Table to Presto's internal Table, a null StorageDescriptor is tolerated only for the dummy/empty path; otherwise convertTable throws HIVE_UNSUPPORTED_FORMAT because the table has no storage definition (columns, location, format).
Source
Thrown at presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/glue/converter/GlueToPrestoConverter.java:96
.setTableName(glueTable.name())
.setOwner(nullToEmpty(glueTable.owner()))
// Athena treats missing table type as EXTERNAL_TABLE.
.setTableType(PrestoTableType.optionalValueOf(glueTable.tableType()).orElse(EXTERNAL_TABLE))
.setParameters(tableParameters)
.setViewOriginalText(Optional.ofNullable(glueTable.viewOriginalText()))
.setViewExpandedText(Optional.ofNullable(glueTable.viewExpandedText()));
StorageDescriptor sd = glueTable.storageDescriptor();
if (isIcebergTable(tableParameters) || (sd == null && isDeltaLakeTable(tableParameters))) {
// Iceberg and Delta Lake tables do not use the StorageDescriptor field, but we need to return a Table so the caller can check that
// the table is an Iceberg/Delta table and decide whether to redirect or fail.
tableBuilder.setDataColumns(ImmutableList.of(new Column("dummy", HIVE_INT, Optional.empty(), Optional.empty())));
tableBuilder.getStorageBuilder().setStorageFormat(StorageFormat.fromHiveStorageFormat(HiveStorageFormat.PARQUET));
tableBuilder.getStorageBuilder().setLocation(sd == null ? "" : sd.location());
}
else {
if (sd == null) {
throw new PrestoException(HIVE_UNSUPPORTED_FORMAT, format("Table StorageDescriptor is null for table %s.%s (%s)", dbName, glueTable.name(), glueTable));
}
tableBuilder.setDataColumns(convertColumns(sd.columns()));
if (glueTable.partitionKeys() != null) {
tableBuilder.setPartitionColumns(convertColumns(glueTable.partitionKeys()));
}
else {
tableBuilder.setPartitionColumns(ImmutableList.of());
}
new StorageConverter().setConvertedStorage(sd, tableBuilder.getStorageBuilder());
}
return tableBuilder.build();
}
private static Column convertColumn(software.amazon.awssdk.services.glue.model.Column glueColumn)
{
return new Column(glueColumn.name(), HiveType.valueOf(glueColumn.type().toLowerCase(Locale.ENGLISH)), Optional.ofNullable(glueColumn.comment()), Optional.empty());View on GitHub (pinned to 55bb57d202)
Solutions
- Fix the table in the Glue console by providing a StorageDescriptor (location, format, columns)
- Recreate the table via CREATE TABLE in Presto/Hive
- Check whatever process produced the table so it writes a complete StorageDescriptor
Defensive patterns
Strategy: validation
Validate before calling
Table glueTable = glueClient.getTable(GetTableRequest.builder().databaseName(db).name(t).build());
if (glueTable.storageDescriptor() == null) {
throw new IllegalStateException("Glue table " + db + "." + t + " has no StorageDescriptor; fix metadata before querying");
} Type guard
boolean queryable = glueTable != null && glueTable.storageDescriptor() != null;
Try / catch
try {
table = metastore.getTable(db, table);
} catch (PrestoException e) {
if (e.getErrorCode().getName().equals("HIVE_UNSUPPORTED_FORMAT")) {
// report broken table metadata to user / skip table
} else throw e;
} Prevention
- Ensure all table-creating pipelines write a full StorageDescriptor
- Monitor Glue catalog for tables missing storage metadata
- Validate tables created by crawlers/external tools
When it happens
Trigger: Reading (getTable) a Glue table whose StorageDescriptor field is null — e.g. a table entry created without storage metadata.
Common situations: Tables created by non-Hive Glue producers (Crawlers edge cases, manual API writes, cross-account copies that stripped StorageDescriptor).
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/47e0b8315f16f359.
Report an issue: GitHub.