{"record":{"id":"6f594fb4d4772c77","repo":"apache/iceberg","slug":"table-s-already-exists-in-the-database-s-and-cat-6f594f","errorCode":null,"errorMessage":"Table %s already exists in the database %s and catalog %s","messagePattern":"Table (.+?) already exists in the database (.+?) and catalog (.+?)","errorType":"exception","errorClass":"AlreadyExistsException","httpStatus":null,"severity":"error","filePath":"flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/FlinkDynamicTableFactory.java","lineNumber":226,"sourceCode":"    if (!flinkCatalog.databaseExists(catalogDatabase)) {\n      try {\n        flinkCatalog.createDatabase(\n            catalogDatabase, new CatalogDatabaseImpl(Maps.newHashMap(), null), true);\n      } catch (DatabaseAlreadyExistException e) {\n        throw new AlreadyExistsException(\n            e,\n            \"Database %s already exists in the iceberg catalog %s.\",\n            catalogName,\n            catalogDatabase);\n      }\n    }\n\n    // Create table if not exists in the external catalog.\n    if (!flinkCatalog.tableExists(objectPath)) {\n      try {\n        flinkCatalog.createIcebergTable(objectPath, resolvedCatalogTable, true);\n      } catch (TableAlreadyExistException e) {\n        throw new AlreadyExistsException(\n            e,\n            \"Table %s already exists in the database %s and catalog %s\",\n            catalogTable,\n            catalogDatabase,\n            catalogName);\n      }\n    }\n\n    return TableLoader.fromCatalog(\n        flinkCatalog.getCatalogLoader(), TableIdentifier.of(catalogDatabase, catalogTable));\n  }\n\n  /**\n   * Merges source catalog properties (catalog name, database, table) with connector properties.\n   * Source catalog name, database, table are serialized as json in FlinkCatalog#getTable to be able\n   * to isolate them from iceberg table props, Here, we flatten and merge them back.\n   *\n   * @param tableProps the existing table properties","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/FlinkDynamicTableFactory.java#L208-L244","documentation":"FlinkDynamicTableFactory auto-creates the Iceberg table (ignoreIfExists=true) if it doesn't exist; if createIcebergTable still reports TableAlreadyExistException, it is rethrown as AlreadyExistsException with this message — a concurrent-creation race between existence check and create.","triggerScenarios":"createTableLoader: tableExists returns false, then another job creates the same table before createIcebergTable completes.","commonSituations":"Parallel job startup against a shared catalog where multiple workers materialize the same sink table.","solutions":["Retry loading the table; it now exists","Sequence table creation before launching parallel jobs","Catch the AlreadyExistsException and treat the table as existing, proceeding with reads/writes"],"exampleFix":"// before\nflinkCatalog.createIcebergTable(objectPath, resolvedCatalogTable, true);\n// after\ntry {\n  flinkCatalog.createIcebergTable(objectPath, resolvedCatalogTable, true);\n} catch (AlreadyExistsException e) {\n  // created concurrently; proceed with existing table\n}","handlingStrategy":"retry","validationCode":"if (catalog.tableExists(objectPath)) { /* skip creation */ }","typeGuard":null,"tryCatchPattern":"try { loader.open(); } catch (AlreadyExistsException e) { /* table created concurrently; proceed with existing */ }","preventionTips":["Pre-create tables before parallel job startup","Serialize DDL steps in deployment pipelines","Idempotent bootstrap scripts"],"tags":["flink","already-exists","race-condition"],"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"}