{"record":{"id":"190c7e4bdc5fe9a4","repo":"apache/iceberg","slug":"replace-failed-e-tag-s-mismatch-for-table-s","errorCode":null,"errorMessage":"Replace failed, E-Tag %s mismatch for table %s","messagePattern":"Replace failed, E-Tag (.+?) mismatch for table (.+?)","errorType":"exception","errorClass":"CommitFailedException","httpStatus":null,"severity":"error","filePath":"dell/src/main/java/org/apache/iceberg/dell/ecs/EcsTableOperations.java","lineNumber":105,"sourceCode":"\n  @Override\n  protected void doCommit(TableMetadata base, TableMetadata metadata) {\n    boolean newTable = base == null;\n    String newMetadataLocation = writeNewMetadataIfRequired(newTable, metadata);\n    if (base == null) {\n      // create a new table, the metadataKey should be absent\n      if (!catalog.putNewProperties(tableObject, buildProperties(newMetadataLocation))) {\n        throw new CommitFailedException(\"Table is existing when create table %s\", tableName());\n      }\n    } else {\n      String cachedETag = eTag;\n      Preconditions.checkNotNull(cachedETag, \"E-Tag must be not null when update table\");\n      // replace to a new version, the E-Tag should be present and matched\n      boolean result =\n          catalog.updatePropertiesObject(\n              tableObject, cachedETag, buildProperties(newMetadataLocation));\n      if (!result) {\n        throw new CommitFailedException(\n            \"Replace failed, E-Tag %s mismatch for table %s\", cachedETag, tableName());\n      }\n    }\n  }\n\n  /** Build properties for table */\n  private Map<String, String> buildProperties(String metadataLocation) {\n    return ImmutableMap.of(ICEBERG_METADATA_LOCATION, metadataLocation);\n  }\n}\n","sourceCodeStart":87,"sourceCodeEnd":116,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/dell/src/main/java/org/apache/iceberg/dell/ecs/EcsTableOperations.java#L87-L116","documentation":"CommitFailedException thrown by EcsTableOperations.doCommit when an optimistic-concurrency replace of the properties object fails because the cached E-Tag no longer matches, meaning another writer updated the table between refresh and commit.","triggerScenarios":"Committing table updates (base != null) when updatePropertiesObject returns false because the stored object's E-Tag differs from the cachedETag captured at load/refresh time.","commonSituations":"Two concurrent writers committing to the same table (common in Spark with multiple tasks/executors), a concurrent drop-and-recreate, or refresh not called before commit.","solutions":["Retry the operation: reload the table (refresh picks up the new state) and re-apply the commit; Iceberg retries CommitFailedException automatically in most engines","Call table.refresh() before committing to reduce stale E-Tag windows","Check for competing writers to the same table"],"exampleFix":"// before\ntable.updateSchema().addColumn(\"c\", Types.LongType.get()).commit(); // stale reference\n// after\ntable.refresh();\ntable.updateSchema().addColumn(\"c\", Types.LongType.get()).commit();","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { table.refresh(); table.update...().commit(); } catch (CommitFailedException e) { table.refresh(); /* retry commit with fresh E-Tag */ }","preventionTips":["Always refresh() before committing on long-lived table references","Minimize the window between refresh and commit","Avoid multiple concurrent writers to the same table where possible"],"tags":["table","ecs","optimistic-concurrency","etag"],"backgroundTag":"checksum-mismatch","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}