{"record":{"id":"300479e192adfa3c","repo":"apache/iceberg","slug":"namespace-s-is-not-empty-one-or-more-tables-exis","errorCode":null,"errorMessage":"Namespace %s is not empty. One or more tables exist.","messagePattern":"Namespace (.+?) is not empty\\. One or more tables exist\\.","errorType":"exception","errorClass":"NamespaceNotEmptyException","httpStatus":409,"severity":"error","filePath":"hive-metastore/src/main/java/org/apache/iceberg/hive/HiveCatalog.java","lineNumber":613,"sourceCode":"      return false;\n    }\n\n    try {\n      clients.run(\n          client -> {\n            client.dropDatabase(\n                namespace.level(0),\n                false /* deleteData */,\n                false /* ignoreUnknownDb */,\n                false /* cascade */);\n            return null;\n          });\n\n      LOG.info(\"Dropped namespace: {}\", namespace);\n      return true;\n\n    } catch (InvalidOperationException e) {\n      throw new NamespaceNotEmptyException(\n          e, \"Namespace %s is not empty. One or more tables exist.\", namespace);\n\n    } catch (NoSuchObjectException e) {\n      return false;\n\n    } catch (TException e) {\n      throw new RuntimeException(\"Failed to drop namespace \" + namespace + \" in Hive Metastore\", e);\n\n    } catch (InterruptedException e) {\n      Thread.currentThread().interrupt();\n      throw new RuntimeException(\n          \"Interrupted in call to drop dropDatabase(name) \" + namespace + \" in Hive Metastore\", e);\n    }\n  }\n\n  @Override\n  public boolean setProperties(Namespace namespace, Map<String, String> properties) {\n    Preconditions.checkArgument(","sourceCodeStart":595,"sourceCodeEnd":631,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/hive-metastore/src/main/java/org/apache/iceberg/hive/HiveCatalog.java#L595-L631","documentation":"dropNamespace converts Hive Metastore's InvalidOperationException into Iceberg's NamespaceNotEmptyException because the database still contains tables. Hive refuses to drop a non-empty database, and the catalog surfaces that as a typed exception.","triggerScenarios":"catalog.dropNamespace(Namespace.of(\"db\"), false) when one or more tables/views still exist in the Hive database 'db'.","commonSituations":"Dropping a database before cleaning up tables; hidden tables registered via other engines (e.g. non-Iceberg tables) keeping the database non-empty; stale metadata listing omitted tables.","solutions":["Drop all tables first: iterate catalog.listTables(namespace) and drop each before dropping the namespace","Use dropNamespace with purge/cascade semantics where supported, or run 'DROP DATABASE ... CASCADE' out-of-band if you accept deleting non-Iceberg objects","Verify emptiness with listTables before dropping"],"exampleFix":"// before\ncatalog.dropNamespace(Namespace.of(\"legacy\"), false);\n// after\nNamespace ns = Namespace.of(\"legacy\");\nfor (TableIdentifier t : catalog.listTables(ns)) {\n  catalog.dropTable(t);\n}\ncatalog.dropNamespace(ns, false);","handlingStrategy":"validation","validationCode":"Namespace ns = Namespace.of(\"legacy\");\nif (!catalog.listTables(ns).isEmpty()) {\n  throw new IllegalStateException(\"Namespace \" + ns + \" still has tables\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  catalog.dropNamespace(ns, false);\n} catch (NamespaceNotEmptyException e) {\n  catalog.listTables(ns).forEach(t -> catalog.dropTable(t));\n  catalog.dropNamespace(ns, false);\n}","preventionTips":["Drop all tables before dropping the namespace","Remember non-Iceberg tables in the same Hive DB also block the drop","Check for views as well as tables"],"tags":["namespace","hive-metastore","drop","not-empty"],"backgroundTag":"invalid-state-transition","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"}