apache/iceberg · error · RuntimeException
Failed to get table metadata for '%s'
Error message
Failed to get table metadata for '%s'
What it means
JdbcSnowflakeClient.loadTableMetadata executes SELECT SYSTEM$GET_ICEBERG_TABLE_INFORMATION(?) and wraps SQLException into 'Failed to get table metadata for %s'. It means the metadata lookup for the Iceberg table failed - the table doesn't exist, the caller lacks privileges, or the query/connection failed. Non-table identifiers are rejected earlier with an IllegalArgumentException, so this message always reflects a query/privilege/existence problem.
Source
Thrown at snowflake/src/main/java/org/apache/iceberg/snowflake/JdbcSnowflakeClient.java:348
@Override
public SnowflakeTableMetadata loadTableMetadata(SnowflakeIdentifier tableIdentifier) {
Preconditions.checkArgument(
tableIdentifier.type() == SnowflakeIdentifier.Type.TABLE,
"loadTableMetadata requires a TABLE identifier, got '%s'",
tableIdentifier);
SnowflakeTableMetadata tableMeta;
try {
final String finalQuery = "SELECT SYSTEM$GET_ICEBERG_TABLE_INFORMATION(?) AS METADATA";
tableMeta =
connectionPool.run(
conn ->
queryHarness.query(
conn,
finalQuery,
TABLE_METADATA_RESULT_SET_HANDLER,
tableIdentifier.toIdentifierString()));
} catch (SQLException e) {
throw snowflakeExceptionToIcebergException(
tableIdentifier,
e,
String.format("Failed to get table metadata for '%s'", tableIdentifier));
} catch (InterruptedException e) {
throw new UncheckedInterruptedException(
e, "Interrupted while getting table metadata for '%s'", tableIdentifier);
}
return tableMeta;
}
@Override
public void close() {
connectionPool.close();
}
private RuntimeException snowflakeExceptionToIcebergException(
SnowflakeIdentifier identifier, SQLException ex, String defaultExceptionMessage) {
// NoSuchNamespace exception for Database and Schema casesView on GitHub (pinned to 86d9c8fc54)
Solutions
- Verify the table exists and is a Snowflake-managed Iceberg table (SHOW ICEBERG TABLES / DESCRIBE TABLE)
- Check the role has sufficient privileges (SELECT or OWNERSHIP) on the table and its database/schema
- Catch the IcebergException and inspect the underlying SQLException error code; handle missing tables by re-listing or throwing NoSuchTableException upstream
- Retry transient failures and validate JDBC auth/connectivity configuration
Example fix
// before
catalog.loadTable(TableIdentifier.of("DB", "SCHEMA", "TBL")); // SQLException -> 'Failed to get table metadata'
// after
try {
catalog.loadTable(TableIdentifier.of("DB", "SCHEMA", "TBL"));
} catch (IcebergException e) {
// inspect e.getCause() SQLException: existence, privileges, or connectivity
// optionally fall back to listIcebergTables to confirm the table exists
} Defensive patterns
Strategy: try-catch
Validate before calling
// confirm the table is a listed Iceberg table before loading metadata
boolean isIceberg = catalog.listTables(Namespace.of(db, schema)).stream()
.anyMatch(t -> t.name().equalsIgnoreCase(tableName));
if (!isIceberg) {
// fail fast with NoSuchTableException instead of a metadata query error
} Try / catch
try {
catalog.loadTable(TableIdentifier.of(db, schema, table));
} catch (IcebergException e) {
SQLException cause = findCause(e, SQLException.class);
if (cause != null && tableMissing(cause.getErrorCode())) {
// handle missing/non-Iceberg table
} else if (isTransient(cause)) {
// retry with backoff
} else {
throw e;
}
} Prevention
- Verify the table exists and is a Snowflake-managed Iceberg table before loading
- Ensure the role has SELECT/OWNERSHIP on the table and USAGE on its parents
- Re-list tables when load fails after a drop/rename to refresh identifiers
- Validate JDBC auth and add retries for transient errors
When it happens
Trigger: Calling loadTableMetadata(tableIdentifier) (used by SnowflakeCatalog.loadTable/refresh to obtain metadata location and registered-time) when the fully qualified table doesn't exist or is not an Iceberg table, the role lacks SELECT/OWNERSHIP privileges, or the JDBC query raises SQLException.
Common situations: Table dropped or renamed before metadata fetch; passing a dynamic/virtual view or non-Iceberg table; wrong case or qualifier in the identifier; expired credentials; transient Snowflake service errors.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- Failed to check if database '%s' exists
- Failed to check if schema '%s' exists
- Interrupted while getting table metadata for '%s'
- Failed to load expected JDBC SnowflakeDriver - if queries fa
- Failed to list databases
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/9f7c90548f72badb.
Report an issue: GitHub.