{"record":{"id":"5f7e69a3dc8ba77f","repo":"prestodb/presto","slug":"metadata-location-s-is-not-same-as-table-metada","errorCode":null,"errorMessage":"Metadata location [%s] is not same as table metadata location [%s] for %s","messagePattern":"Metadata location \\[(.+?)\\] is not same as table metadata location \\[(.+?)\\] for (.+?)","errorType":"exception","errorClass":"CommitFailedException","httpStatus":null,"severity":"warning","filePath":"presto-iceberg/src/main/java/com/facebook/presto/iceberg/HiveTableOperations.java","lineNumber":282,"sourceCode":"                        parameters.put(TABLE_COMMENT, tableComment);\n                    }\n                    Table.Builder builder = Table.builder()\n                            .setDatabaseName(database)\n                            .setTableName(tableName)\n                            .setOwner(owner.orElseThrow(() -> new IllegalStateException(\"Owner not set\")))\n                            .setTableType(PrestoTableType.EXTERNAL_TABLE)\n                            .setDataColumns(toHiveColumns(metadata.schema().columns()))\n                            .withStorage(storage -> storage.setLocation(metadata.location()))\n                            .withStorage(storage -> storage.setStorageFormat(STORAGE_FORMAT))\n                            .setParameters(parameters);\n                    table = builder.build();\n                }\n                else {\n                    Table currentTable = getTable();\n                    checkState(currentMetadataLocation != null, \"No current metadata location for existing table\");\n                    String metadataLocation = currentTable.getParameters().get(METADATA_LOCATION);\n                    if (!currentMetadataLocation.equals(metadataLocation)) {\n                        throw new CommitFailedException(\"Metadata location [%s] is not same as table metadata location [%s] for %s\", currentMetadataLocation, metadataLocation, getSchemaTableName());\n                    }\n                    table = Table.builder(currentTable)\n                            .setDataColumns(toHiveColumns(metadata.schema().columns()))\n                            .withStorage(storage -> storage.setLocation(metadata.location()))\n                            .setParameter(METADATA_LOCATION, newMetadataLocation)\n                            .setParameter(PREVIOUS_METADATA_LOCATION, currentMetadataLocation)\n                            .build();\n                }\n            }\n            catch (RuntimeException e) {\n                try {\n                    io().deleteFile(newMetadataLocation);\n                }\n                catch (RuntimeException exception) {\n                    e.addSuppressed(exception);\n                }\n                throw e;\n            }","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-iceberg/src/main/java/com/facebook/presto/iceberg/HiveTableOperations.java#L264-L300","documentation":"HiveTableOperations.commit() performs optimistic concurrency: before writing new Iceberg metadata it compares the METADATA_LOCATION parameter it read earlier against the current value in the Hive Metastore. If they differ, another process committed to the table in between, and this CommitFailedException aborts the write so Iceberg can retry with fresh state.","triggerScenarios":"Calling commit() (e.g. via table.refresh() + new snapshot, schema change, or Iceberg DDL) while the METADATA_LOCATION property in HMS no longer equals the baseMetadataLocation captured when the operation started.","commonSituations":"Two writers (different Presto clusters, Spark, Flink, or a compaction/maintenance job) committing to the same Iceberg table concurrently; long-running queries whose commit phase races with another commit; stale table handle reused after another commit.","solutions":["Retry the operation: re-read the table (refresh) so the new base metadata location is picked up, then re-apply the change.","Ensure only one writer path modifies the table (disable conflicting maintenance jobs or coordinate schedules).","If using an external commit lock, verify lock configuration so concurrent commits are serialized.","Upgrade Iceberg/Hive connectors if retry loops fail repeatedly due to known commit races."],"exampleFix":"// before\nTable table = loadTable(session, tableName); // loaded long ago\ntransaction(table).updateSchema(...).commit();\n// after\nTable table = loadTable(session, tableName);\ntable.refresh(); // re-read latest metadata before committing\ntransaction(table).updateSchema(...).commit();","handlingStrategy":"retry","validationCode":"Table t = loadTable(...); t.refresh(); // confirm METADATA_LOCATION unchanged before a long-running commit","typeGuard":null,"tryCatchPattern":"try { table.newAppend().appendFile(f).commit(); }\ncatch (CommitFailedException e) { table.refresh(); /* retry write once or twice */ }","preventionTips":["Always refresh the table right before committing.","Avoid multiple writers without a commit lock.","Keep write transactions short to reduce race windows."],"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"}