{"record":{"id":"8cc21a45f3d1713e","repo":"apache/iceberg","slug":"illegal-table-name-8cc21a","errorCode":null,"errorMessage":"Illegal table name:","messagePattern":"Illegal table name:","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/FlinkCatalog.java","lineNumber":166,"sourceCode":"    String[] namespace = new String[baseNamespace.levels().length + 1];\n    System.arraycopy(baseNamespace.levels(), 0, namespace, 0, baseNamespace.levels().length);\n    namespace[baseNamespace.levels().length] = newLevel;\n    return Namespace.of(namespace);\n  }\n\n  TableIdentifier toIdentifier(ObjectPath path) {\n    String objectName = path.getObjectName();\n    List<String> tableName = Splitter.on('$').splitToList(objectName);\n\n    if (tableName.size() == 1) {\n      return TableIdentifier.of(\n          appendLevel(baseNamespace, path.getDatabaseName()), path.getObjectName());\n    } else if (tableName.size() == 2 && MetadataTableType.from(tableName.get(1)) != null) {\n      return TableIdentifier.of(\n          appendLevel(appendLevel(baseNamespace, path.getDatabaseName()), tableName.get(0)),\n          tableName.get(1));\n    } else {\n      throw new IllegalArgumentException(\"Illegal table name:\" + objectName);\n    }\n  }\n\n  @Override\n  public List<String> listDatabases() throws CatalogException {\n    if (asNamespaceCatalog == null) {\n      return Collections.singletonList(getDefaultDatabase());\n    }\n\n    return asNamespaceCatalog.listNamespaces(baseNamespace).stream()\n        .map(n -> n.level(n.levels().length - 1))\n        .collect(Collectors.toList());\n  }\n\n  @Override\n  public CatalogDatabase getDatabase(String databaseName)\n      throws DatabaseNotExistException, CatalogException {\n    if (asNamespaceCatalog == null) {","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/FlinkCatalog.java#L148-L184","documentation":"FlinkCatalog.toIdentifier converts a Flink ObjectPath (catalog.database.table) into an Iceberg TableIdentifier. After mapping namespace levels and any metadata-table suffix, the resulting table name has an unexpected number of parts, so the input object name is rejected as an illegal table name. The message ends with the offending objectName.","triggerScenarios":"Calling table(), tableExists(), dropTable(), renameTable(), createIcebergTable(), or createTableLoader() with an ObjectPath whose object name resolves to more than two levels or an unrecognized second segment — e.g. names containing extra dots producing a 3+ element tableName list, or a second segment that is not a known MetadataTableType.","commonSituations":"Quoting/dotted identifiers in Flink SQL producing multi-level names; typo'd metadata table names (e.g. 'snapshotss' instead of 'snapshots'); passing fully-qualified names into APIs expecting a simple object name.","solutions":["Use a table name without extra dot-separated levels, or properly quote the identifier in Flink SQL","If reading a metadata table, use an exact valid suffix: snapshots, history, files, manifests, refs, partitions, all_data_files, etc.","Check the objectName does not embed database qualification when passed to toIdentifier","Log/inspect the failing objectName in the message and correct the call site"],"exampleFix":"// before\ncatalog.dropTable(new ObjectPath(db, \"mytable.snapshots.typo\"));\n// after\ncatalog.dropTable(new ObjectPath(db, \"mytable.snapshots\")); // valid metadata table name","handlingStrategy":"validation","validationCode":"ObjectPath path = ...;\nString name = path.getObjectName();\nif (name.contains(\".\")) {\n  String[] parts = name.split(\"\\\\.\");\n  if (parts.length > 2 || (parts.length == 2 && MetadataTableType.from(parts[1]) == null)) {\n    throw new IllegalArgumentException(\"unsupported table name: \" + name);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  catalog.table(objectPath);\n} catch (IllegalArgumentException e) {\n  LOG.error(\"bad table identifier: {}\", objectPath.getObjectName());\n  throw e;\n}","preventionTips":["Quote dotted identifiers in Flink SQL so they do not split into extra name levels","Use exact metadata-table suffixes (snapshots, files, manifests, refs, history, partitions)","Never pass fully-qualified 3-part names where an ObjectPath is expected"],"tags":["flink","catalog","identifier","naming"],"backgroundTag":"invalid-identifier-format","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}