{"record":{"id":"d21490ecfc2bd2d6","repo":"apache/iceberg","slug":"cannot-use-non-v1-table-s-as-a-source-d21490","errorCode":null,"errorMessage":"Cannot use non-v1 table '%s' as a source","messagePattern":"Cannot use non-v1 table '(.+?)' as a source","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/actions/BaseTableCreationSparkAction.java","lineNumber":82,"sourceCode":"  private final Identifier sourceTableIdent;\n\n  // Optional Parameters for destination\n  private final Map<String, String> additionalProperties = Maps.newHashMap();\n\n  BaseTableCreationSparkAction(\n      SparkSession spark, CatalogPlugin sourceCatalog, Identifier sourceTableIdent) {\n    super(spark);\n\n    this.sourceCatalog = checkSourceCatalog(sourceCatalog);\n    this.sourceTableIdent = sourceTableIdent;\n\n    try {\n      this.sourceTable = (V1Table) this.sourceCatalog.loadTable(sourceTableIdent);\n      this.sourceCatalogTable = sourceTable.v1Table();\n    } catch (org.apache.spark.sql.catalyst.analysis.NoSuchTableException e) {\n      throw new NoSuchTableException(\"Cannot find source table '%s'\", sourceTableIdent);\n    } catch (ClassCastException e) {\n      throw new IllegalArgumentException(\n          String.format(\"Cannot use non-v1 table '%s' as a source\", sourceTableIdent), e);\n    }\n    validateSourceTable();\n\n    this.sourceTableLocation =\n        CatalogUtils.URIToString(sourceCatalogTable.storage().locationUri().get());\n  }\n\n  protected abstract TableCatalog checkSourceCatalog(CatalogPlugin catalog);\n\n  protected abstract StagingTableCatalog destCatalog();\n\n  protected abstract Identifier destTableIdent();\n\n  protected abstract Map<String, String> destTableProps();\n\n  protected String sourceTableLocation() {\n    return sourceTableLocation;","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/actions/BaseTableCreationSparkAction.java#L64-L100","documentation":"The action casts the loaded source table to Spark's V1Table; if the catalog returns a different CatalogTable implementation (V2 or non-v1), ClassCastException is caught and rethrown as IllegalArgumentException 'Cannot use non-v1 table'. The action only supports V1 table sources.","triggerScenarios":"snapshot/migrate-style actions where the source resolves through a catalog that returns a V2Table (e.g. Spark's built-in v2 catalog, JDBC v2, or another Iceberg catalog plugin) rather than V1Table.","commonSituations":"Migrating from a table in the Iceberg spark catalog itself (already Iceberg → returns v2); using spark_catalog with a session catalog that doesn't expose V1Table; mixing catalog plugins.","solutions":["Source the table from a catalog that exposes V1Table (e.g. default spark_catalog for Hive/Parquet sources)","Use a different action appropriate for Iceberg-to-Iceberg copies (e.g. snapshot against an Iceberg table is unnecessary — register the table instead)","Check which catalog plugin the source identifier resolves through"],"exampleFix":"// before\nCALL spark_catalog.system.migrate('iceberg_db.tbl') // source is v2\n// after\nCALL spark_catalog.system.migrate('parquet_db.tbl') // source is a v1/Hive table","handlingStrategy":"type-guard","validationCode":"CatalogPlugin cat = ...; Table loaded = cat.loadTable(ident); // confirm it maps to V1Table before invoking the action","typeGuard":"boolean isV1Source(CatalogTable t) { return t instanceof V1Table; }","tryCatchPattern":"try { callAction(...); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"non-v1 table\")) { /* choose different source catalog */ } throw e; }","preventionTips":["Source migrate/snapshot actions from Hive/parquet tables via spark_catalog (V1)","Do not migrate tables already managed by Iceberg — register instead","Check which CatalogPlugin implementation resolves the source identifier"],"tags":["spark","catalog","type-mismatch"],"backgroundTag":"incompatible-source-type","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"}