Why is my catalog not finding my Iceberg table?
Summary
- Spark finds an Iceberg table only through a catalog registered with
spark.sql.catalog.<name>properties, and it resolves your table name against the current catalog and namespace. Check the catalog, namespace and table in the identifier first. - Then check the catalog settings: the implementation class (
SparkCatalogorSparkSessionCatalog),type,uriandwarehouse. The Hive-based catalog only loads Iceberg tables. - Make sure the Iceberg Spark runtime JAR matches your Spark and Scala versions.
- The Iceberg catalog cache is on by default, and entries expire after 30 seconds.
- For a Databricks table read from an external engine, check the Iceberg REST endpoint, the
warehousecatalog name, external data access, theEXTERNAL USE SCHEMAprivilege, and that views cannot be read.
Why is my catalog not finding my Iceberg table?
Why can't Spark find my Iceberg table?
Spark finds an Iceberg table only through a catalog that you register with spark.sql.catalog.<name> properties, and it resolves the name in your query against the current catalog and namespace. Check the identifier first, then the catalog settings, then the runtime JAR, then the cache.
How does Spark resolve an Iceberg table name?
The Iceberg docs list how spark.table(table) and spark.read.format("iceberg").load(table) read the identifier:
| Identifier | What Spark loads |
|---|---|
file:///path/to/table |
a HadoopTable at the given path |
tablename |
tablename in the current catalog and namespace |
catalog.tablename |
tablename from the specified catalog |
namespace.tablename |
namespace.tablename from the current catalog |
catalog.namespace.tablename |
namespace.tablename from the specified catalog |
namespace1.namespace2.tablename |
that table from the current catalog |
The docs list these forms in order of priority, so a matching catalog name takes priority over any namespace resolution. Spark 3 tracks the current catalog and namespace. Run SHOW CURRENT NAMESPACE to see them and USE local.db; to change them.
How do I check what Spark can see?
spark.catalog.currentCatalog()
spark.catalog.listCatalogs()
spark.catalog.listDatabases()
spark.catalog.listTables("local.db")
The PySpark Catalog API returns the current catalog, the catalogs available in the session, the namespaces in the current catalog, and the tables in a namespace (the name may be qualified with a catalog). Compare the output with the identifier in your query. The catalog-aware calls need Spark 3.4 or later.
What does a working configuration look like?
The Iceberg Spark quickstart adds the runtime JAR, adds Iceberg support to Spark's built-in catalog, and creates a path-based catalog named local for tables under $PWD/warehouse:
spark-sql --packages org.apache.iceberg:iceberg-spark-runtime-4.1_2.13:1.12.0 \
--conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
--conf spark.sql.catalog.spark_catalog=org.apache.iceberg.spark.SparkSessionCatalog \
--conf spark.sql.catalog.spark_catalog.type=hive \
--conf spark.sql.catalog.local=org.apache.iceberg.spark.SparkCatalog \
--conf spark.sql.catalog.local.type=hadoop \
--conf spark.sql.catalog.local.warehouse=$PWD/warehouse
CREATE TABLE local.db.table (id bigint, data string) USING iceberg;
INSERT INTO local.db.table VALUES (1, 'a'), (2, 'b'), (3, 'c');
SELECT count(1) as count, data FROM local.db.table GROUP BY data;
Which catalog settings hide a table?
| Setting | What the Iceberg docs say |
|---|---|
spark.sql.catalog.<name> |
The implementation class. SparkCatalog supports Hive, Hadoop, REST, JDBC, Nessie and other catalogs. SparkSessionCatalog adds Iceberg support to Spark's built-in catalog and delegates non-Iceberg tables to it. |
type |
hive, hadoop, rest, jdbc, nessie or unset for a custom catalog. If type is null, catalog-impl must not be null. |
uri |
The Hive metastore URL for a hive catalog, or the REST URL for a rest catalog. For hive, omit it to use hive.metastore.uris from hive-site.xml. |
warehouse |
The base path for the warehouse directory. |
default-namespace |
The default current namespace for the catalog. The default value is default. |
cache-enabled |
Catalog cache, true by default. Entries expire after cache.expiration-interval-ms, which is 30 seconds by default. |
Two more checks. The Hive-based catalog only loads Iceberg tables, so use a session catalog to load non-Iceberg tables from the same metastore. And Iceberg publishes one runtime JAR per Spark and Scala version, for example iceberg-spark-runtime-3.5_2.12. Besides vendor dependencies and storage bundles, the runtime JAR is the only addition the classpath needs.
Why can't my external engine find a Databricks table?
Unity Catalog on Databricks uses a three-level namespace, catalog.schema.object. An external Spark session reaches its Iceberg tables through the Iceberg REST catalog at /api/2.1/unity-catalog/iceberg-rest. If the table is not found, check:
- Catalog entry. Set
type=rest, the endpointuri, andwarehouseto the Unity Catalog catalog name. Databricks says to configure each catalog separately. - Access. External data access must be enabled on the metastore, and the principal needs the
EXTERNAL USE SCHEMAprivilege on the schema. - Table type. Managed Iceberg tables, foreign Iceberg tables and Delta tables with Iceberg reads enabled are available. External Iceberg clients cannot access views.
- Freshness. Foreign Iceberg tables are not refreshed automatically. Run
REFRESH FOREIGN TABLEto read the latest snapshot.
To test the endpoint without Spark, load the table with the REST API:
curl -X GET -H "Authorization: Bearer $OAUTH_TOKEN" -H "Accept: application/json" \
https://<workspace-instance>/api/2.1/unity-catalog/iceberg-rest/v1/catalogs/<uc_catalog_name>/namespaces/<uc_schema_name>/tables/<uc_table_name>
FAQs
Can I use more than one Iceberg catalog in a session?
Yes. A catalog is created and named by adding a spark.sql.catalog.<catalog-name> property with an implementation class, and its other properties nest under that name.
How do I make Spark's built-in catalog load Iceberg tables?
Configure spark_catalog to use Iceberg's SparkSessionCatalog, as the quickstart does with type=hive. It is useful when spark_catalog must work with both Iceberg and non-Iceberg tables in the same metastore.
Can I read an Iceberg table without registering a catalog?
Yes, by path. The Iceberg docs say the identifier file:///path/to/table loads a HadoopTable at the given path when you call spark.read.format("iceberg").load(table).
The information provided herein is for general informational purposes only and may not reflect the most current product capabilities or configurations.