apache/iceberg · error · UnsupportedOperationException
this.getClass().getName() + " does not implement buildTable"
Error message
this.getClass().getName() + " does not implement buildTable"
What it means
Catalog.buildTable(identifier, schema) is a default method that throws UnsupportedOperationException naming the concrete class that failed to implement it. It is the entry point for all builder-based table operations (create, replace, stage, transactions), so any catalog that does not override it cannot participate in these flows. The message includes the class name to identify which catalog lacks the implementation.
Source
Thrown at api/src/main/java/org/apache/iceberg/catalog/Catalog.java:393
*/
default Table registerTable(
TableIdentifier identifier, String metadataFileLocation, boolean overwrite) {
if (!overwrite) {
return registerTable(identifier, metadataFileLocation);
}
throw new UnsupportedOperationException("Registering tables with overwrite is not supported");
}
/**
* Instantiate a builder to either create a table or start a create/replace transaction.
*
* @param identifier a table identifier
* @param schema a schema
* @return the builder to create a table or start a create/replace transaction
*/
default TableBuilder buildTable(TableIdentifier identifier, Schema schema) {
throw new UnsupportedOperationException(
this.getClass().getName() + " does not implement buildTable");
}
/**
* Initialize a catalog given a custom name and a map of catalog properties.
*
* <p>A custom Catalog implementation must have a no-arg constructor. A compute engine like Spark
* or Flink will first initialize the catalog without any arguments, and then call this method to
* complete catalog initialization with properties passed into the engine.
*
* @param name a custom name for the catalog
* @param properties catalog properties
*/
default void initialize(String name, Map<String, String> properties) {}
/**
* A builder used to create valid {@link Table tables} or start create/replace {@link Transaction
* transactions}.View on GitHub (pinned to 86d9c8fc54)
Solutions
- Implement buildTable(identifier, schema) returning a real TableBuilder in the custom catalog implementation
- Use a fully-featured catalog implementation (Hive, JDBC, REST, Nessie) instead of the partial one
- In test code, replace the stub catalog with a full mock/stub that returns a builder
- If using a third-party catalog, upgrade it to a version supporting the TableBuilder API
Example fix
// before
class MyCatalog implements Catalog { /* buildTable not overridden */ }
catalog.createTable(ident, schema);
// after
class MyCatalog implements Catalog {
@Override
public TableBuilder buildTable(TableIdentifier ident, Schema schema) {
return new MyTableBuilder(ident, schema);
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// Reject incomplete Catalog implementations at wiring time
if (catalog.buildTable(ident, schema) instanceof UnsupportedTableBuilder) { ... } // or catch at first use Try / catch
try {
TableBuilder b = catalog.buildTable(ident, schema);
} catch (UnsupportedOperationException e) {
throw new IllegalStateException("Catalog does not implement buildTable: " + e.getMessage(), e);
} Prevention
- Always implement buildTable when writing a custom Catalog; it underpins create/replace/transaction flows
- Use CatalogUtil or extend BaseCatalog to inherit builder plumbing
- Keep custom catalogs compiling against the current Iceberg API version
- Smoke-test createTable/stageCreate/transaction paths for any new catalog implementation
When it happens
Trigger: Calling catalog.buildTable(ident, schema), or any API that routes through it (createTable via builder path, newCreateTableTransaction, stageTableCreate, tableBuilder, transaction(tableBuilder)) on a Catalog implementation that does not override buildTable.
Common situations: Implementing a minimal custom Catalog (e.g. for tests or a thin wrapper) that satisfies name()/listTables()/dropTable() but not the builder method; passing a partial Catalog mock into code that calls buildTable; using an older third-party catalog written before buildTable was added.
Related errors
- Registering tables is not supported
- Registering tables with overwrite is not supported
- Can't retrieve values from an empty struct
- Can't modify an empty struct
- %s doesn't implement cleanupLevel
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/326575d09b7644a3.
Report an issue: GitHub.