{"record":{"id":"56b88607a8d56b28","repo":"apache/iceberg","slug":"class-name-does-not-support-purging-tables","errorCode":null,"errorMessage":"${CLASS_NAME} does not support purging tables","messagePattern":"(.+?) does not support purging tables","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/SparkRewriteTableCatalog.java","lineNumber":95,"sourceCode":"  public SparkTable createTable(\n      Identifier ident, StructType schema, Transform[] partitions, Map<String, String> properties)\n      throws TableAlreadyExistsException {\n    throw new UnsupportedOperationException(CLASS_NAME + \" does not support creating tables\");\n  }\n\n  @Override\n  public SparkTable alterTable(Identifier ident, TableChange... changes) {\n    throw new UnsupportedOperationException(CLASS_NAME + \" does not support altering tables\");\n  }\n\n  @Override\n  public boolean dropTable(Identifier ident) {\n    throw new UnsupportedOperationException(CLASS_NAME + \" does not support dropping tables\");\n  }\n\n  @Override\n  public boolean purgeTable(Identifier ident) throws UnsupportedOperationException {\n    throw new UnsupportedOperationException(CLASS_NAME + \" does not support purging tables\");\n  }\n\n  @Override\n  public void renameTable(Identifier oldIdent, Identifier newIdent) {\n    throw new UnsupportedOperationException(CLASS_NAME + \" does not support renaming tables\");\n  }\n\n  @Override\n  public void initialize(String catalogName, CaseInsensitiveStringMap options) {\n    this.name = catalogName;\n  }\n\n  @Override\n  public String name() {\n    return name;\n  }\n\n  private void validateNoNamespace(Identifier ident) {","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/SparkRewriteTableCatalog.java#L77-L113","documentation":"SparkRewriteTableCatalog supports only staged table creation for rewrite procedures; purging (dropping plus deleting all data/metadata files) is a destructive DDL operation it does not implement, so purgeTable always throws UnsupportedOperationException naming the class.","triggerScenarios":"Calling purgeTable(ident) directly, or executing SQL that maps to purge (e.g. DROP TABLE PURGE in Spark when the target resolves to this catalog).","commonSituations":"Retention/cleanup jobs issuing DROP TABLE ... PURGE against a misconfigured catalog; testing code against the rewrite catalog instead of the production catalog.","solutions":["Point the table's catalog at SparkCatalog or the real underlying Iceberg catalog (Hive/REST/Hadoop) before purging","Use the staging/rewrite catalog only for its supported stageCreate/stageReplace flows","Handle UnsupportedOperationException explicitly and delegate purge to the correct catalog"],"exampleFix":"// before\ncatalog(asTableCatalog(\"rewrite\")).purgeTable(ident);\n// after\ncatalog(asTableCatalog(\"prod\")).purgeTable(ident);","handlingStrategy":"try-catch","validationCode":"if (catalog instanceof SparkRewriteTableCatalog) {\n  // purge must go to the real catalog\n  return;\n}","typeGuard":"boolean supportsPurge(Catalog c) { return !(c instanceof SparkRewriteTableCatalog); }","tryCatchPattern":"try {\n  catalog.purgeTable(ident);\n} catch (UnsupportedOperationException e) {\n  prodCatalog.purgeTable(ident);\n}","preventionTips":["Keep purge/retention jobs pointed at the production catalog","Do not expose the rewrite catalog in user-facing session configs","Test cleanup pipelines with the catalog implementations used in production"],"tags":["spark","unsupported-operation","catalog"],"backgroundTag":"unsupported-operation","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"}