prestodb/presto · error · PrestoException

HIVE_INVALID_METADATA

HIVE_INVALID_METADATA

Error message

Table is missing storage descriptor

What it means

The table record was found but its StorageDescriptor (sd) is null, which is malformed Hive metadata — every table should carry a storage descriptor describing columns, input/output formats, and location. getFields throws HIVE_INVALID_METADATA to surface corrupt metastore data instead of a confusing NPE.

Source

Thrown at presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/thrift/HiveMetastore.java:183

        throw new UnsupportedOperationException();
    }

    default boolean isTableOwner(MetastoreContext metastoreContext, String user, String databaseName, String tableName)
    {
        // a table can only be owned by a user
        Optional<Table> table = getTable(metastoreContext, databaseName, tableName);
        return table.isPresent() && user.equals(table.get().getOwner());
    }

    default Optional<List<FieldSchema>> getFields(MetastoreContext metastoreContext, String databaseName, String tableName)
    {
        Optional<Table> table = getTable(metastoreContext, databaseName, tableName);
        if (!table.isPresent()) {
            throw new TableNotFoundException(new SchemaTableName(databaseName, tableName));
        }

        if (table.get().getSd() == null) {
            throw new PrestoException(HIVE_INVALID_METADATA, "Table is missing storage descriptor");
        }

        return Optional.of(table.get().getSd().getCols());
    }

    default Optional<PrimaryKeyConstraint<String>> getPrimaryKey(MetastoreContext metastoreContext, String databaseName, String tableName)
    {
        return Optional.empty();
    }

    default List<UniqueConstraint<String>> getUniqueConstraints(MetastoreContext metastoreContext, String databaseName, String tableName)
    {
        return ImmutableList.of();
    }

    default List<NotNullConstraint<String>> getNotNullConstraints(MetastoreContext metastoreContext, String databaseName, String tableName)
    {
        return ImmutableList.of();

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Drop and recreate the table from DDL; repopulate data if it lives in the underlying storage.
  2. Inspect the metastore backend ( HMS RDBMS 'SDS' table) to confirm the null SD and repair the row via Hive tooling.
  3. Restore the table metadata from a valid backup or re-run the creating job.
  4. Run msck/repair and Hive 'DESCRIBE' on the table to detect further corruption; upgrade the metastore if a known bug produced null SDs.

Example fix

// before
SELECT * FROM hive.web.broken; -- sd == null
// after
DROP TABLE hive.web.broken;
CREATE TABLE hive.web.broken (...) WITH (format = 'ORC', location = 's3://...');
MSCK REPAIR TABLE hive.web.broken;
Defensive patterns

Strategy: validation

Validate before calling

-- detect malformed table before querying
SHOW CREATE TABLE <database>.<tableName>;
-- fails or shows no column/storage info for corrupted tables

Try / catch

try {
    columns = metadata.getColumnHandles(session, tableHandle);
} catch (PrestoException e) {
    if (HiveErrorCode.HIVE_INVALID_METADATA.toErrorCode().equals(e.getErrorCode())) {
        // drop/recreate table or restore metastore metadata
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Reading fields of a table whose metastore row was written incompletely (failed DDL), hand-edited, or corrupted by a buggy metastore/backup-restore process.

Common situations: Interrupted CREATE TABLE leaving partial rows; direct manipulation of the metastore RDBMS; restore from backup losing the SD blob; third-party tools writing tables without an SD; corrupt Glue/metadata sync.

Related errors


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