apache/iceberg · error · RuntimeException
Failed to list tables for scope
Error message
Failed to list tables for scope '%s'
What it means
JdbcSnowflakeClient.listIcebergTables runs 'SHOW ICEBERG TABLES ... IN ACCOUNT/DATABASE/SCHEMA IDENTIFIER(?)' and converts SQLException into 'Failed to list tables for scope %s'. This means the SHOW ICEBERG TABLES statement failed on the Snowflake side - missing parent namespace, insufficient privileges, connection issues, or server error. Interrupted calls raise UncheckedInterruptedException instead.
Solutions
- Confirm the database/schema path exists with exact casing (SHOW SCHEMAS IN DATABASE ...) before listing tables
- Grant the role USAGE privileges on the parent database and schema
- Catch NoSuchNamespaceException for expected missing scopes; inspect the IcebergException cause SQLException otherwise
- Retry on transient errors and validate JDBC connectivity/auth configuration
Example fix
// before
catalog.listTables(Namespace.of("DB", "SCHEMA")); // SQLException -> 'Failed to list tables'
// after
try {
catalog.listTables(Namespace.of("DB", "SCHEMA"));
} catch (NoSuchNamespaceException e) {
// scope missing - create or correct the namespace
} catch (IcebergException e) {
// check cause: privileges, auth, connectivity
} Defensive patterns
Strategy: try-catch
Validate before calling
// verify the namespace path exists before listing tables catalog.listNamespaces(Namespace.of(dbName)); // throws NoSuchNamespaceException if absent catalog.listNamespaces(Namespace.of(dbName, schemaName));
Try / catch
try {
catalog.listTables(Namespace.of(dbName, schemaName));
} catch (NoSuchNamespaceException e) {
// missing scope: create it or return empty listing
} catch (IcebergException e) {
SQLException cause = findCause(e, SQLException.class);
// classify via cause.getErrorCode(): privileges/auth vs transient; retry transient
} Prevention
- Confirm database and schema exist with exact casing before listing tables
- Grant role USAGE on parent database/schema
- Handle NoSuchNamespaceException explicitly for optional scopes
- Add backoff-based retries for transient Snowflake/network errors
When it happens
Trigger: Calling listIcebergTables(scope) (e.g., SnowflakeCatalog.listTables) with a database or schema that doesn't exist or is inaccessible, wrong identifier casing, insufficient role privileges to show Iceberg tables, or a JDBC failure.
Common situations: Listing tables in a schema that was dropped; role without privileges on the parent database/schema; case-mismatched namespace names; transient Snowflake/network errors during Spark or Flink metadata queries.
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
- Failed to check if schema
- Failed to get table metadata for
- Failed to list databases
- Failed to list schemas for scope
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/1708e300576fe455.
Report an issue: GitHub.
Appendix: source
Thrown at snowflake/src/main/java/org/apache/iceberg/snowflake/JdbcSnowflakeClient.java:314
// schema-level listing
baseQuery.append(" IN SCHEMA IDENTIFIER(?)");
queryParams = new String[] {scope.toIdentifierString()};
break;
default:
throw new IllegalArgumentException(
String.format("Unsupported scope type for listIcebergTables: %s", scope));
}
final String finalQuery = baseQuery.toString();
final String[] finalQueryParams = queryParams;
List<SnowflakeIdentifier> tables;
try {
tables =
connectionPool.run(
conn ->
queryHarness.query(conn, finalQuery, TABLE_RESULT_SET_HANDLER, finalQueryParams));
} catch (SQLException e) {
throw snowflakeExceptionToIcebergException(
scope, e, String.format("Failed to list tables for scope '%s'", scope));
} catch (InterruptedException e) {
throw new UncheckedInterruptedException(
e, "Interrupted while listing tables for scope '%s'", scope);
}
tables.forEach(
table ->
Preconditions.checkState(
table.type() == SnowflakeIdentifier.Type.TABLE,
"Expected TABLE, got identifier '%s' for scope '%s'",
table,
scope));
return tables;
}
@Override
public SnowflakeTableMetadata loadTableMetadata(SnowflakeIdentifier tableIdentifier) {
Preconditions.checkArgument(View on GitHub (pinned to 86d9c8fc54)