{"record":{"id":"bd604ecbdc56aa9a","repo":"apache/iceberg","slug":"deletes-are-supported-in-v2-and-above","errorCode":null,"errorMessage":"Deletes are supported in V2 and above","messagePattern":"Deletes are supported in V2 and above","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/MergingSnapshotProducer.java","lineNumber":298,"sourceCode":"    if (ContentFileUtil.isDV(file)) {\n      List<DeleteFile> dvsForReferencedFile =\n          dvsByReferencedFile.computeIfAbsent(\n              file.referencedDataFile(), newFile -> Lists.newArrayList());\n      dvsForReferencedFile.add(file);\n    } else {\n      v2Deletes.add(file);\n    }\n  }\n\n  protected void validateNewDeleteFile(DeleteFile file) {\n    Preconditions.checkNotNull(file, \"Invalid delete file: null\");\n    validateDeleteFileForVersion(file, formatVersion());\n  }\n\n  private static void validateDeleteFileForVersion(DeleteFile file, int formatVersion) {\n    switch (formatVersion) {\n      case 1:\n        throw new IllegalArgumentException(\"Deletes are supported in V2 and above\");\n      case 2:\n        Preconditions.checkArgument(\n            file.content() == FileContent.EQUALITY_DELETES || !ContentFileUtil.isDV(file),\n            \"Must not use DVs for position deletes in V2: %s\",\n            ContentFileUtil.dvDesc(file));\n        break;\n      case 3:\n      case 4:\n        Preconditions.checkArgument(\n            file.content() == FileContent.EQUALITY_DELETES || ContentFileUtil.isDV(file),\n            \"Must use DVs for position deletes in V%s: %s\",\n            formatVersion,\n            file.location());\n        break;\n      default:\n        throw new IllegalArgumentException(\"Unsupported format version: \" + formatVersion);\n    }\n  }","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/MergingSnapshotProducer.java#L280-L316","documentation":"Thrown by MergingSnapshotProducer.validateDeleteFileForVersion when a delete file is being added to (or validated against) a table whose format version is 1. Delete files (position and equality deletes) were introduced in format version 2, so any attempt to commit deletes to a v1 table fails fast with this IllegalArgumentException.","triggerScenarios":"Calling newRowDelta() or newOverwrite() with a DeleteFile on a table with formatVersion=1; also triggered by validateDeleteFilesForVersion when inherited/delete files exist on a v1 table.","commonSituations":"Adding deletes to old pre-v2 tables that were never upgraded; cluster/tooling that defaults new tables to formatVersion 1; copy/migrate jobs that pass delete files from a v2 table to a v1 table.","solutions":["Upgrade the table: UPDATE the table format version (table.updateProperties or rewrite with table property 'format-version'='2' at creation) and re-run the operation","Create new tables with format-version=2 or 3 if delete support is needed","Remove the delete-file path from the v1 table operation (use rewrite/overwrite instead of deletes)","Check Spark/Engine table creation properties ensuring format-version>=2"],"exampleFix":"// before: v1 table cannot take deletes\ntable.newRowDelta().addDeletes(deleteFile).commit();\n// after: set format version before creating the table\nMap<String,String> props = Map.of(TableProperties.FORMAT_VERSION, \"2\");\ntables.create(schema, PartitionSpec.unpartitioned(), props, \"s3://bucket/table\");","handlingStrategy":"validation","validationCode":"boolean deletesSupported = table.ops().current().formatVersion() >= 2;\nif (!deletesSupported) throw new IllegalStateException(\"Upgrade table to format-version >= 2 before committing delete files\");","typeGuard":null,"tryCatchPattern":"try { rowDelta.commit(); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"V2 and above\")) { /* migrate table or use rewrite instead */ } throw e; }","preventionTips":["Always create new tables with format-version >= 2 when deletes are planned","Check table.ops().current().formatVersion() before delete paths","Migrate legacy v1 tables before enabling delete workloads","Document format-version requirements in job configuration"],"tags":["format-version","delete-files","validation"],"backgroundTag":"unsupported-operation","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"}