{"record":{"id":"a19faf1cbfafa6ff","repo":"apache/druid","slug":"tried-to-insert-a-duplicate-table-s","errorCode":null,"errorMessage":"Tried to insert a duplicate table: %s","messagePattern":"Tried to insert a duplicate table: (.+?)","errorType":"exception","errorClass":"DuplicateKeyException","httpStatus":null,"severity":"error","filePath":"extensions-core/druid-catalog/src/main/java/org/apache/druid/catalog/storage/sql/SQLCatalogManager.java","lineNumber":167,"sourceCode":"            {\n              final TableSpec spec = table.spec();\n              final long updateTime = System.currentTimeMillis();\n              final Update stmt = handle\n                  .createStatement(statement(INSERT_TABLE))\n                  .bind(SCHEMA_NAME_COL, table.id().schema())\n                  .bind(TABLE_NAME_COL, table.id().name())\n                  .bind(CREATION_TIME_COL, updateTime)\n                  .bind(UPDATE_TIME_COL, updateTime)\n                  .bind(STATE_COL, TableMetadata.TableState.ACTIVE.code())\n                  .bind(TABLE_TYPE_COL, spec.type())\n                  .bind(PROPERTIES_COL, JacksonUtils.toBytes(jsonMapper, spec.properties()))\n                  .bind(COLUMNS_COL, JacksonUtils.toBytes(jsonMapper, spec.columns()));\n              try {\n                stmt.execute();\n              }\n              catch (UnableToExecuteStatementException e) {\n                if (DbUtils.isDuplicateRecordException(e)) {\n                  throw new DuplicateKeyException(\n                        \"Tried to insert a duplicate table: %s\",\n                        table.sqlName()\n                  );\n                } else {\n                  throw e;\n                }\n              }\n              sendAddition(table, updateTime);\n              return updateTime;\n            }\n          }\n      );\n    }\n    catch (CallbackFailedException e) {\n      if (e.getCause() instanceof DuplicateKeyException) {\n        throw (DuplicateKeyException) e.getCause();\n      }\n      throw e;","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/druid-catalog/src/main/java/org/apache/druid/catalog/storage/sql/SQLCatalogManager.java#L149-L185","documentation":"When inserting a new catalog table into the DB, the INSERT hits a unique-constraint violation (DuplicateKeyException path after DbUtils.isDuplicateRecordException). The manager maps the raw JDBC error to this DuplicateKeyException naming the table, because a table with the same name already exists.","triggerScenarios":"Calling SQLCatalogManager.createTable (through its JDBI withHandle callback) with a TableId whose sqlName already has a row in the catalog table definition table, causing the INSERT to violate the primary/unique key.","commonSituations":"Client-side create raced with another process creating the same table without a lock or prior exists() check; retry logic re-running a create that already succeeded; concurrent tooling or automation double-registering a table.","solutions":["Check existence first with the manager's readTable/exists API before calling createTable, or catch DuplicateKeyException and treat it as 'already created'.","Use the table lock (createTable under lock when available) so concurrent creators serialize.","If a retry caused it, switch create retry logic to idempotent upsert (alterTable/createTable-if-absent semantics).","Inspect the DB directly (SELECT from the catalog table table) to confirm the existing row and decide whether to reuse or delete it."],"exampleFix":"// before\nmanager.createTable(id, spec); // throws DuplicateKeyException if it exists\n\n// after\nif (manager.readTable(id) == null) {\n  manager.createTable(id, spec);\n}","handlingStrategy":"try-catch","validationCode":"if (manager.readTable(id) != null) {\n  throw new IllegalStateException(\"Table already exists: \" + id.sqlName());\n}","typeGuard":null,"tryCatchPattern":"try {\n  manager.createTable(id, spec);\n} catch (DuplicateKeyException e) {\n  // treat as already-created; fall back to readTable\n  existing = manager.readTable(id);\n}","preventionTips":["Check existence before create; make create logic idempotent.","Route all table creation through the manager's locking to serialize writers.","Avoid blind retries of create calls without checking prior success."],"tags":["sql","duplicate-key","catalog"],"backgroundTag":"file-already-exists","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}