prestodb/presto · critical · PrestoException

ICEBERG_INVALID_METADATA

ICEBERG_INVALID_METADATA

Error message

Unable to read metadata file %s

What it means

When loading an Iceberg table, the connector parses the metadata JSON file pointed to by the metastore's metadata_location. If TableMetadataParser.read fails for any reason (missing/corrupt file, unreadable JSON, filesystem access error), Presto wraps the failure in ICEBERG_INVALID_METADATA with 'Unable to read metadata file <location>'.

Source

Thrown at presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergHiveMetadata.java:754

    @Override
    public void registerTable(ConnectorSession clientSession, SchemaTableName schemaTableName, Path metadataLocation, boolean deleteDataOnDrop)
    {
        String tableLocation = metadataLocation.getName();
        HdfsContext hdfsContext = new HdfsContext(
                clientSession,
                schemaTableName.getSchemaName(),
                schemaTableName.getTableName(),
                tableLocation,
                true);

        InputFile inputFile = new HdfsInputFile(metadataLocation, hdfsEnvironment, hdfsContext);
        TableMetadata tableMetadata;
        try {
            tableMetadata = TableMetadataParser.read(new HdfsFileIO(manifestFileCache, hdfsEnvironment, hdfsContext), inputFile);
        }
        catch (Exception e) {
            throw new PrestoException(ICEBERG_INVALID_METADATA, String.format("Unable to read metadata file %s", metadataLocation), e);
        }

        Table.Builder builder = Table.builder()
                .setDatabaseName(schemaTableName.getSchemaName())
                .setTableName(schemaTableName.getTableName())
                .setOwner(clientSession.getUser())
                .setDataColumns(toHiveColumns(tableMetadata.schema().columns()))
                .setTableType(PrestoTableType.EXTERNAL_TABLE)
                .withStorage(storage -> storage.setLocation(tableMetadata.location()))
                .withStorage(storage -> storage.setStorageFormat(STORAGE_FORMAT))
                .setParameter("EXTERNAL", "TRUE")
                .setParameter(BaseMetastoreTableOperations.TABLE_TYPE_PROP, BaseMetastoreTableOperations.ICEBERG_TABLE_TYPE_VALUE.toUpperCase(ENGLISH))
                .setParameter(BaseMetastoreTableOperations.METADATA_LOCATION_PROP, tableMetadata.metadataFileLocation())
                .setParameter(HiveTableOperations.PRESTO_DELETE_DATA_ON_DROP, String.valueOf(deleteDataOnDrop));
        Table table = builder.build();

        PrestoPrincipal owner = new PrestoPrincipal(USER, table.getOwner());
        PrincipalPrivileges privileges = new PrincipalPrivileges(

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Verify the metadata file exists and is readable at the metadata_location shown by the metastore table properties
  2. Restore the file from backup or re-point metadata_location to a valid earlier metadata JSON (via the engine that wrote the table)
  3. Fix filesystem access: check permissions and credentials for the Presto user on the metadata path
  4. Upgrade Presto (or the writer) so Iceberg metadata format versions are compatible
  5. Roll back or repair the table using an Iceberg repair tool with a valid snapshot

Example fix

// before
-- metastore metadata_location -> /warehouse/t/metadata/00003-...metadata.json (deleted)
// after
-- re-point to an existing metadata file (via Spark/expert tooling):
-- metadata_location = /warehouse/t/metadata/00001-...metadata.json
Defensive patterns

Strategy: try-catch

Validate before calling

-- Verify the current metadata file exists and is readable:
-- metastore property metadata_location -> check the path on the filesystem (hdfs dfs -ls / hdfs dfs -cat ...tail of file)

Try / catch

try (ResultSet rs = stmt.executeQuery("SELECT * FROM iceberg.sales.events")) {
    ...
} catch (SQLException e) {
    if (e.getMessage() != null && e.getMessage().contains("Unable to read metadata file")) {
        // restore/re-point metadata JSON, check permissions, or repair the table
    } else { throw e; }
}

Prevention

When it happens

Trigger: Querying or opening a table whose metadata_location points to a deleted, truncated, corrupt, or inaccessible metadata JSON; HDFS/S3 permission errors reading the file; version skew between the writer's metadata format and the parser.

Common situations: Metadata files cleaned up by an aggressive expiration job while the metastore pointer is stale; manually moved/renamed files; object-store outages or credentials expiring mid-read; table written by a newer Iceberg version than Presto supports.

Related errors


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