apache/iceberg · error · IllegalArgumentException
Illegal table name:
Error message
Illegal table name:
What it means
FlinkCatalog.toIdentifier converts a Flink ObjectPath into an Iceberg TableIdentifier relative to the catalog's base namespace. If the resulting name cannot be represented — e.g. the table name has more levels than expected or the metadata-table mapping fails — it throws IllegalArgumentException 'Illegal table name:'. It signals the requested name is not addressable through this catalog, not that the table is missing.
Source
Thrown at flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/FlinkCatalog.java:166
String[] namespace = new String[baseNamespace.levels().length + 1];
System.arraycopy(baseNamespace.levels(), 0, namespace, 0, baseNamespace.levels().length);
namespace[baseNamespace.levels().length] = newLevel;
return Namespace.of(namespace);
}
TableIdentifier toIdentifier(ObjectPath path) {
String objectName = path.getObjectName();
List<String> tableName = Splitter.on('$').splitToList(objectName);
if (tableName.size() == 1) {
return TableIdentifier.of(
appendLevel(baseNamespace, path.getDatabaseName()), path.getObjectName());
} else if (tableName.size() == 2 && MetadataTableType.from(tableName.get(1)) != null) {
return TableIdentifier.of(
appendLevel(appendLevel(baseNamespace, path.getDatabaseName()), tableName.get(0)),
tableName.get(1));
} else {
throw new IllegalArgumentException("Illegal table name:" + objectName);
}
}
@Override
public List<String> listDatabases() throws CatalogException {
if (asNamespaceCatalog == null) {
return Collections.singletonList(getDefaultDatabase());
}
return asNamespaceCatalog.listNamespaces(baseNamespace).stream()
.map(n -> n.level(n.levels().length - 1))
.collect(Collectors.toList());
}
@Override
public CatalogDatabase getDatabase(String databaseName)
throws DatabaseNotExistException, CatalogException {
if (asNamespaceCatalog == null) {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Use a two-part ObjectPath (database.object) matching the catalog's expected nesting; avoid extra levels.
- If targeting an Iceberg metadata table, use an exact supported suffix (e.g. 'tbl.history', 'tbl.snapshots').
- Print the full objectName being passed and correct the caller (SQL path, connector options) that built it.
- For deep namespaces, configure the Flink catalog's base namespace so remaining depth is exactly 2.
Example fix
// before
ObjectPath path = new ObjectPath("db", "a.b.c"); // too many levels
// after
ObjectPath path = new ObjectPath("db", "tbl"); // database.table
// or for metadata tables:
ObjectPath metaPath = new ObjectPath("db", "tbl.snapshots"); Defensive patterns
Strategy: validation
Validate before calling
// validate object path arity before calling catalog methods
static void checkPath(ObjectPath path) {
String name = path.getObjectName();
boolean isMetadataTable = name != null && MetadataTableType.from(name) != null;
// plain table: objectName has no dot; metadata table: exactly one dot with valid suffix
if (name.contains(".") && !isMetadataTable) {
throw new IllegalArgumentException("unsupported table name: " + name);
}
} Try / catch
try {
catalog.dropTable(path);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Illegal table name")) {
throw new ValidationException("cannot address " + path + " through this catalog: " + e.getMessage(), e);
}
throw e;
} Prevention
- Build ObjectPath with exactly database + table, never deeper nesting
- Use exact Iceberg metadata-table suffixes (snapshots, history, files, ...) when targeting them
- Check Flink SQL identifier quoting so 'db.tbl' is not parsed as extra levels
When it happens
Trigger: Calling table/tableExists/dropTable/renameTable/createTableLoader with an ObjectPath whose name is neither a plain table nor a recognized 2-part metadata table form; nested or malformed identifiers (extra dots, wrong depth) passed from Flink SQL or the API.
Common situations: Referencing tables with unusual quoting in Flink SQL ('cat.db.db2.tbl' against a single-level catalog), typos in metadata-table suffixes, programmatic ObjectPath construction with the wrong arity.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Illegal table name:
- Invalid table identifier: %s
- Invalid identifier: %s
- Invalid view identifier: %s
- Illegal table name:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/c7c5dd7e4091627d.
Report an issue: GitHub.