{"record":{"id":"e504d0884682f661","repo":"prestodb/presto","slug":"iceberg-commit-error-e504d0","errorCode":"ICEBERG_COMMIT_ERROR","errorMessage":"Failed to commit Iceberg update to table: ${writableTableHandle.getTableName()}","messagePattern":"Failed to commit Iceberg update to table: (.+?)","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergAbstractMetadata.java","lineNumber":771,"sourceCode":"                .map(slice -> commitTaskCodec.fromJson(slice.getBytes()))\n                .collect(toImmutableList());\n\n        ImmutableSet.Builder<String> writtenFiles = ImmutableSet.builder();\n\n        SchemaTableName schemaTableName = new SchemaTableName(writableTableHandle.getSchemaName(), writableTableHandle.getTableName().getTableName());\n        Table icebergTable = getIcebergTable(session, schemaTableName);\n        AppendFiles appendFiles = icebergTable.newAppend();\n        Optional<String> branchName = writableTableHandle.getTableName().getBranchName();\n        branchName.ifPresent(appendFiles::toBranch);\n\n        commitTasks.forEach(task -> handleInsertTask(task, icebergTable, appendFiles, writtenFiles));\n        try {\n            appendFiles.set(PRESTO_QUERY_ID, session.getQueryId());\n            appendFiles.commit();\n        }\n        catch (ValidationException e) {\n            log.error(e, \"ValidationException in finishWrite\");\n            throw new PrestoException(ICEBERG_COMMIT_ERROR, \"Failed to commit Iceberg update to table: \" + writableTableHandle.getTableName(), e);\n        }\n\n        return Optional.of(new HiveOutputMetadata(new HiveOutputInfo(commitTasks.stream()\n                .map(CommitTaskData::getPath)\n                .collect(toImmutableList()), icebergTable.location())));\n    }\n\n    private Optional<ConnectorOutputMetadata> finishWrite(ConnectorSession session, SchemaTableName tableName, IcebergWritableTableHandle writableTableHandle, Collection<Slice> fragments, ChangelogOperation operationType)\n    {\n        if (fragments.isEmpty()) {\n            return Optional.empty();\n        }\n\n        Table icebergTable = getIcebergTable(session, tableName);\n\n        List<CommitTaskData> commitTasks = fragments.stream()\n                .map(slice -> commitTaskCodec.fromJson(slice.getBytes()))\n                .collect(toImmutableList());","sourceCodeStart":753,"sourceCodeEnd":789,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergAbstractMetadata.java#L753-L789","documentation":"This error is thrown by finishInsert when an Iceberg ValidationException is raised while committing appended data files to the table via appendFiles.commit(). It wraps the underlying Iceberg conflict/validation failure so the query fails with ICEBERG_COMMIT_ERROR instead of an internal Iceberg type.","triggerScenarios":"An INSERT (or CREATE TABLE AS) finishes writing data files and calls appendFiles.commit(), but Iceberg rejects the metadata commit — typically because the table's snapshot changed concurrently (ConcurrentModificationException-style ValidationException) or the appended files fail snapshot validation.","commonSituations":"Concurrent writers committing to the same Iceberg table during a long INSERT; long-running CTAS queries whose target table snapshot was replaced mid-query; Iceberg table mutated by compaction/expiry jobs while an insert commits.","solutions":["Retry the INSERT query; Iceberg commits are optimistic and the write may succeed when re-run.","Reduce concurrency on the table: serialize writes or enable/rely on Iceberg optimistic-concurrency retry behavior in the engine.","Check the wrapped ValidationException in the Presto log for the exact cause (e.g. snapshot conflict, schema change) and address that root cause.","Shorten write duration so fewer concurrent commits overlap."],"exampleFix":"// before\nINSERT INTO iceberg_table SELECT * FROM large_source; // long-running, conflicts with other writers\n// after\n-- retry, or partition the load:\nINSERT INTO iceberg_table SELECT * FROM large_source WHERE partition = 'a';\nINSERT INTO iceberg_table SELECT * FROM large_source WHERE partition = 'b';","handlingStrategy":"retry","validationCode":"-- before inserting, check for concurrent writers / inspect snapshot age\nSELECT * FROM \"t$snapshots\" LIMIT 1;","typeGuard":null,"tryCatchPattern":"// catch PrestoException with code ICEBERG_COMMIT_ERROR, back off, retry insert\ntry { insert(...); }\ncatch (PrestoException e) {\n  if (e.getErrorCode().getCode() == ICEBERG_COMMIT_ERROR.toErrorCode().getCode()) retryWithBackoff();\n  else throw e;\n}","preventionTips":["Avoid many concurrent writers to the same Iceberg table","Split very large inserts into smaller batches to shorten commit windows","Schedule compaction/expiry jobs outside heavy write windows"],"tags":["iceberg","commit-conflict","concurrency","insert"],"backgroundTag":"optimistic-concurrency-commit-conflict","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"}