{"record":{"id":"8eb379a13424a98d","repo":"apache/iceberg","slug":"table-was-created-concurrently-s","errorCode":null,"errorMessage":"Table was created concurrently: %s","messagePattern":"Table was created concurrently: (.+?)","errorType":"exception","errorClass":"AlreadyExistsException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/BaseMetastoreCatalog.java","lineNumber":203,"sourceCode":"      return this;\n    }\n\n    @Override\n    public Table create() {\n      TableOperations ops = newTableOps(identifier);\n      if (ops.current() != null) {\n        throw new AlreadyExistsException(\"Table already exists: %s\", identifier);\n      }\n\n      String baseLocation = location != null ? location : defaultWarehouseLocation(identifier);\n      tableProperties.putAll(tableOverrideProperties());\n      TableMetadata metadata =\n          TableMetadata.newTableMetadata(schema, spec, sortOrder, baseLocation, tableProperties);\n\n      try {\n        ops.commit(null, metadata);\n      } catch (CommitFailedException ignored) {\n        throw new AlreadyExistsException(\"Table was created concurrently: %s\", identifier);\n      }\n\n      return new BaseTable(ops, fullTableName(name(), identifier), metricsReporter());\n    }\n\n    @Override\n    public Transaction createTransaction() {\n      TableOperations ops = newTableOps(identifier);\n      if (ops.current() != null) {\n        throw new AlreadyExistsException(\"Table already exists: %s\", identifier);\n      }\n\n      String baseLocation = location != null ? location : defaultWarehouseLocation(identifier);\n      tableProperties.putAll(tableOverrideProperties());\n      TableMetadata metadata =\n          TableMetadata.newTableMetadata(schema, spec, sortOrder, baseLocation, tableProperties);\n      return Transactions.createTableTransaction(\n          identifier.toString(), ops, metadata, metricsReporter());","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/BaseMetastoreCatalog.java#L185-L221","documentation":"Thrown when create() passed the initial existence pre-check (ops.current() was null) but the subsequent ops.commit(null, metadata) failed with CommitFailedException, meaning another writer created the table between the check and the commit. This is the race-condition guard for concurrent table creation on metastore catalogs.","triggerScenarios":"Two processes/threads call create() for the same table identifier concurrently; the losing committer's null-base commit fails and is converted to this AlreadyExistsException.","commonSituations":"Parallel Spark/Flink jobs or schedulers launching the same DDL simultaneously; orchestrator retries after a timeout where the first attempt actually succeeded; multi-region or shared metastore setups with competing writers.","solutions":["Catch AlreadyExistsException and treat creation as successful (load the existing table)","Retry the whole operation, this time taking the load-existing path","Serialize DDL through a single pipeline/scheduler so only one writer creates tables","Use catalog-level locking or a coordination mechanism for table creation"],"exampleFix":"// before\ncatalog.buildTable(ident, schema).create();\n// after\ntry {\n  catalog.buildTable(ident, schema).create();\n} catch (AlreadyExistsException e) {\n  Table table = catalog.loadTable(ident); // lost a creation race; use the winner's table\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { catalog.buildTable(ident, schema).create(); }\ncatch (AlreadyExistsException e) { /* lost creation race; load the table */ table = catalog.loadTable(ident); }","preventionTips":["Treat creation races as benign and fall back to loading the existing table","Serialize DDL through a single orchestrator","Retry on CommitFailedException with fresh metadata"],"tags":["catalog","race-condition","concurrent-ddl"],"backgroundTag":"file-already-exists","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}