{"record":{"id":"24dc4365dee51e99","repo":"apache/iceberg","slug":"table-already-exists-s-24dc43","errorCode":null,"errorMessage":"Table already exists: %s","messagePattern":"Table already exists: (.+?)","errorType":"exception","errorClass":"AlreadyExistsException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/BaseMetastoreCatalog.java","lineNumber":83,"sourceCode":"    } else {\n      throw new NoSuchTableException(\"Invalid table identifier: %s\", identifier);\n    }\n\n    LOG.info(\"Table loaded by catalog: {}\", result);\n    return result;\n  }\n\n  @Override\n  public Table registerTable(TableIdentifier identifier, String metadataFileLocation) {\n    Preconditions.checkArgument(\n        identifier != null && isValidIdentifier(identifier), \"Invalid identifier: %s\", identifier);\n    Preconditions.checkArgument(\n        metadataFileLocation != null && !metadataFileLocation.isEmpty(),\n        \"Cannot register an empty metadata file location as a table\");\n\n    // Throw an exception if this table already exists in the catalog.\n    if (tableExists(identifier)) {\n      throw new AlreadyExistsException(\"Table already exists: %s\", identifier);\n    }\n\n    TableOperations ops = newTableOps(identifier);\n    InputFile metadataFile = ops.io().newInputFile(metadataFileLocation);\n    TableMetadata metadata = TableMetadataParser.read(metadataFile);\n    ops.commit(null, metadata);\n\n    return new BaseTable(ops, fullTableName(name(), identifier), metricsReporter());\n  }\n\n  @Override\n  public TableBuilder buildTable(TableIdentifier identifier, Schema schema) {\n    return new BaseMetastoreCatalogTableBuilder(identifier, schema);\n  }\n\n  private Table loadMetadataTable(TableIdentifier identifier) {\n    String tableName = identifier.name();\n    MetadataTableType type = MetadataTableType.from(tableName);","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/BaseMetastoreCatalog.java#L65-L101","documentation":"registerTable attaches an existing metadata.json to a new identifier, but the catalog refuses to overwrite an existing table. It throws AlreadyExistsException when tableExists(identifier) is true, mirroring the REST/409 'already exists' convention.","triggerScenarios":"Calling catalog.registerTable(identifier, metadataFileLocation) where a table (or metadata table name collision) already exists at that identifier in this catalog.","commonSituations":"Re-running a migration/import script without drop or idempotency; registering into the wrong catalog where the name is taken; concurrent registration jobs.","solutions":["Drop the existing table first or choose a new identifier","Check catalog.tableExists(identifier) before registering and skip if present","Make registration idempotent by catching AlreadyExistsException and verifying metadata equality"],"exampleFix":"// before\ncatalog.registerTable(ident, metadataLocation); // AlreadyExistsException on re-run\n// after\nif (!catalog.tableExists(ident)) {\n  catalog.registerTable(ident, metadataLocation);\n}","handlingStrategy":"try-catch","validationCode":"if (catalog.tableExists(identifier)) { skip or fail fast; }","typeGuard":null,"tryCatchPattern":"try { catalog.registerTable(ident, loc); } catch (AlreadyExistsException e) { logger.info(\"Table {} already registered, skipping\", ident); }","preventionTips":["Check tableExists before registerTable","Make migration scripts idempotent","Use unique target identifiers per run or drop first"],"tags":["catalog","already-exists","registration","conflict"],"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"}