{"record":{"id":"a87db10809284ba4","repo":"prestodb/presto","slug":"iceberg-invalid-format-version","errorCode":"ICEBERG_INVALID_FORMAT_VERSION","errorMessage":"Iceberg table updates require at least format version 2 and update mode must be merge-on-read","messagePattern":"Iceberg table updates require at least format version 2 and update mode must be merge-on-read","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergAbstractMetadata.java","lineNumber":939,"sourceCode":"    public ConnectorMergeTableHandle beginMerge(ConnectorSession session, ConnectorTableHandle tableHandle)\n    {\n        shouldRunInAutoCommitTransaction(\"MERGE INTO\");\n        IcebergTableHandle icebergTableHandle = (IcebergTableHandle) tableHandle;\n        verify(icebergTableHandle.getIcebergTableName().getTableType() == DATA, \"only the data table can have data merged\");\n        Table icebergTable = getIcebergTable(session, icebergTableHandle.getSchemaTableName());\n        validateBranchExists(icebergTableHandle, icebergTable);\n        int formatVersion = ((BaseTable) icebergTable).operations().current().formatVersion();\n\n        if (formatVersion > MAX_FORMAT_VERSION_FOR_ROW_LEVEL_OPERATIONS) {\n            throw new PrestoException(NOT_SUPPORTED,\n                    format(\"Iceberg table updates for format version %s are not supported yet\", formatVersion));\n        }\n\n        if (formatVersion < MIN_FORMAT_VERSION_FOR_DELETE ||\n                !Optional.ofNullable(icebergTable.properties().get(TableProperties.UPDATE_MODE))\n                        .map(mode -> mode.equals(MERGE_ON_READ.modeName()))\n                        .orElse(false)) {\n            throw new PrestoException(ICEBERG_INVALID_FORMAT_VERSION,\n                    \"Iceberg table updates require at least format version 2 and update mode must be merge-on-read\");\n        }\n        validateTableMode(session, icebergTable);\n\n        IcebergInsertTableHandle insertHandle = new IcebergInsertTableHandle(\n                icebergTableHandle.getSchemaName(),\n                icebergTableHandle.getIcebergTableName(),\n                toPrestoSchema(icebergTable.schema(), typeManager),\n                toPrestoPartitionSpec(icebergTable.spec(), typeManager),\n                getColumns(icebergTable.schema(), icebergTable.spec(), typeManager),\n                icebergTable.location(),\n                getFileFormat(icebergTable),\n                getCompressionCodec(session),\n                icebergTable.properties(),\n                getSupportedSortFields(icebergTable.schema(), icebergTable.sortOrder()),\n                Optional.empty());\n\n        Map<Integer, PrestoIcebergPartitionSpec> partitionSpecs = transformValues(icebergTable.specs(), partitionSpec -> toPrestoPartitionSpec(partitionSpec, typeManager));","sourceCodeStart":921,"sourceCodeEnd":957,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergAbstractMetadata.java#L921-L957","documentation":"Thrown when a row-level update targets an Iceberg table that either has format version below 2 (no delete files) or is not configured with update.mode=merge-on-read. Row-level DML requires v2 semantics and merge-on-read mode in this connector.","triggerScenarios":"Running MERGE/UPDATE/DELETE against a format-version-1 table, or a v2 table whose table property update.mode is not set to merge-on-read (e.g. copy-on-write).","commonSituations":"Legacy tables created before the engine supported v2; tables created with copy-on-write defaults; properties changed or never set after upgrading Presto.","solutions":["Set the table property update.mode=merge-on-read, e.g. ALTER TABLE ... SET TBLPROPERTIES ('update.mode'='merge-on-read').","Upgrade the table to format version 2 (rewrite the table or set format-version via a supported writer).","Recreate the table with format-version=2 and merge-on-read mode before running row-level DML."],"exampleFix":"// before\nMERGE INTO t ...; -- t is format version 1 / copy-on-write\n// after\nALTER TABLE t SET TBLPROPERTIES ('update.mode' = 'merge-on-read', 'format-version' = '2');\nMERGE INTO t ...;","handlingStrategy":"validation","validationCode":"-- verify format version and update mode before MERGE/UPDATE/DELETE\nSELECT key, value FROM \"t$properties\" WHERE key IN ('format-version', 'update.mode');\n-- proceed only if format-version >= 2 and update.mode = merge-on-read","typeGuard":null,"tryCatchPattern":"try { merge(...); }\ncatch (PrestoException e) { if (ICEBERG_INVALID_FORMAT_VERSION.equals(e.getErrorCode())) { /* set table properties and retry */ } }","preventionTips":["Create Iceberg tables with format-version=2 by default","Set update.mode=merge-on-read on tables used for DML","Audit table properties after migrations between engines"],"tags":["iceberg","format-version","merge-on-read","table-properties"],"backgroundTag":"iceberg-format-version-unsupported","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}