{"record":{"id":"8a7a670d82925ccb","repo":"apache/iceberg","slug":"namespace-s-is-not-empty-contains-d-table-s-8a7a67","errorCode":null,"errorMessage":"Namespace %s is not empty. Contains %d table(s).","messagePattern":"Namespace (.+?) is not empty\\. Contains (.+?) table\\(s\\)\\.","errorType":"exception","errorClass":"NamespaceNotEmptyException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/jdbc/JdbcCatalog.java","lineNumber":555,"sourceCode":"    }\n  }\n\n  @Override\n  public boolean dropNamespace(Namespace namespace) throws NamespaceNotEmptyException {\n    if (!namespaceExists(namespace)) {\n      return false;\n    }\n\n    List<Namespace> childNamespaces = listNamespaces(namespace);\n    if (childNamespaces != null && !childNamespaces.isEmpty()) {\n      throw new NamespaceNotEmptyException(\n          \"Namespace %s is not empty. Contains %d child namespace(s).\",\n          namespace, childNamespaces.size());\n    }\n\n    List<TableIdentifier> tableIdentifiers = listTables(namespace);\n    if (tableIdentifiers != null && !tableIdentifiers.isEmpty()) {\n      throw new NamespaceNotEmptyException(\n          \"Namespace %s is not empty. Contains %d table(s).\", namespace, tableIdentifiers.size());\n    }\n\n    if (schemaVersion != JdbcUtil.SchemaVersion.V0) {\n      List<TableIdentifier> viewIdentifiers = listViews(namespace);\n      if (viewIdentifiers != null && !viewIdentifiers.isEmpty()) {\n        throw new NamespaceNotEmptyException(\n            \"Namespace %s is not empty. Contains %d view(s).\", namespace, viewIdentifiers.size());\n      }\n    }\n\n    int deletedRows =\n        execute(\n            JdbcUtil.DELETE_ALL_NAMESPACE_PROPERTIES_SQL,\n            catalogName,\n            JdbcUtil.namespaceToString(namespace));\n\n    return deletedRows > 0;","sourceCodeStart":537,"sourceCodeEnd":573,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/jdbc/JdbcCatalog.java#L537-L573","documentation":"dropNamespace throws NamespaceNotEmptyException when the namespace still contains tables. Tables under the namespace block its deletion even if child namespaces were already removed. The message reports the number of blocking tables.","triggerScenarios":"Calling catalog.dropNamespace(ns) while listTables(ns) returns identifiers and the namespace's child-namespace check has already passed.","commonSituations":"Cleanup jobs that drop namespaces without purging tables first; abandoned tables from failed pipelines; users expecting dropNamespace to cascade (it does not).","solutions":["Drop all tables via catalog.dropTable(identifier) before dropping the namespace","Use catalog.listTables(ns) to enumerate and handle each table (drop or rename out)","Catch NamespaceNotEmptyException and inspect listTables to report leftover tables to the operator"],"exampleFix":"// before\ncatalog.dropNamespace(ns);\n// after\nfor (TableIdentifier t : catalog.listTables(ns)) {\n  catalog.dropTable(t);\n}\ncatalog.dropNamespace(ns);","handlingStrategy":"validation","validationCode":"if (!catalog.listTables(ns).isEmpty()) { throw new IllegalStateException(\"namespace has tables\"); }","typeGuard":"boolean dropSafe = catalog.listTables(ns).isEmpty() && catalog.listViews(ns).isEmpty();","tryCatchPattern":"try { catalog.dropNamespace(ns); } catch (NamespaceNotEmptyException e) { /* enumerate listTables, drop each, retry */ }","preventionTips":["Enumerate listTables(ns) and drop each table before dropNamespace","Do not expect cascading deletes from dropNamespace","Include table purge steps in all environment teardown jobs"],"tags":["jdbc-catalog","namespace-not-empty","tables"],"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-23T08:17:48.524Z"}