{"record":{"id":"f934eabe812fc8c8","repo":"prestodb/presto","slug":"the-table-s-s-has-been-modified-concurrently","errorCode":null,"errorMessage":"The table %s.%s has been modified concurrently","messagePattern":"The table (.+?)\\.(.+?) has been modified concurrently","errorType":"exception","errorClass":"CommitFailedException","httpStatus":null,"severity":"warning","filePath":"presto-iceberg/src/main/java/com/facebook/presto/iceberg/HiveTableOperations.java","lineNumber":351,"sourceCode":"                            \"Failed to acquire locks from metastore because the underlying metastore \"\n                                    + \"table 'HIVE_LOCKS' does not exist. This can occur when using an embedded metastore which does not \"\n                                    + \"support transactions. To fix this use an alternative metastore.\",\n                            e);\n                }\n                CommitStatus commitStatus;\n                if (e.getMessage() != null\n                        && e.getMessage()\n                        .contains(\n                                \"The table has been modified. The parameter value for key '\"\n                                        + METADATA_LOCATION_PROP\n                                        + \"' is\")) {\n                    // It's possible the HMS client incorrectly retries a successful operation, due to network\n                    // issue for example, and triggers this exception. So we need double-check to make sure\n                    // this is really a concurrent modification. Hitting this exception means no pending\n                    // requests, if any, can succeed later, so it's safe to check status in strict mode\n                    commitStatus = checkCommitStatusStrict(newMetadataLocation, metadata);\n                    if (commitStatus == FAILED) {\n                        throw new CommitFailedException(\n                                e, \"The table %s.%s has been modified concurrently\", database, tableName);\n                    }\n                }\n                else {\n                    // Cannot tell if commit to succeeded, attempting to reconnect and check.\n                    commitStatus = checkCommitStatus(newMetadataLocation, metadata);\n                }\n                switch (commitStatus) {\n                    case SUCCESS:\n                        break;\n                    case FAILED:\n                        throw e;\n                    case UNKNOWN:\n                        throw new CommitStateUnknownException(e);\n                }\n            }\n            deleteRemovedMetadataFiles(base, metadata);\n        }","sourceCodeStart":333,"sourceCodeEnd":369,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-iceberg/src/main/java/com/facebook/presto/iceberg/HiveTableOperations.java#L333-L369","documentation":"commit() failed with an exception (e.g. InterruptedException / MetastoreException) suggesting the table changed concurrently. Before giving up, Presto re-checks whether the new metadata location was actually committed (checkCommitStatusStrict); if not committed (FAILED) it throws CommitFailedException 'The table <db>.<table> has been modified concurrently'.","triggerScenarios":"Concurrent commit to the same Iceberg table where another writer updated METADATA_LOCATION, plus retry/connection quirks from the HMS client (e.g. HMS retrying a failed operation).","commonSituations":"Multiple engines (Spark, Flink, Presto) or jobs writing the same table simultaneously; network retries from the HMS client causing duplicate commit attempts.","solutions":["Retry the whole write after table.refresh() so the commit is based on the latest metadata location.","Serialize writers: run compaction/optimization jobs and query engines so they don't commit simultaneously.","Configure a proper commit lock (HMS lock or external lock) to avoid concurrent commits.","If this appears spuriously, check HMS client retry policy and network stability between Presto and HMS."],"exampleFix":"// before\nTable table = catalog.loadTable(identifier);\ntable.newAppend().appendFile(dataFile).commit(); // may race\n// after\nTable table = catalog.loadTable(identifier);\ntable.refresh();\ntable.newAppend().appendFile(dataFile).commit(); // retry on CommitFailedException","handlingStrategy":"retry","validationCode":"table.refresh(); long expected = ((IcebergTableHandle) handle).getSnapshotId(); // detect concurrent modification before write","typeGuard":null,"tryCatchPattern":"try { commit(); }\ncatch (CommitFailedException e) { table.refresh(); retryWrite(); }","preventionTips":["Serialize commits with a lock or single-writer policy.","Refresh before every commit.","Keep HMS client retries conservative to avoid duplicate commits."],"tags":["iceberg","concurrency","commit-conflict","hive-metastore"],"backgroundTag":"optimistic-concurrency-commit-failed","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"}