{"record":{"id":"482110dbbdd2db2d","repo":"apache/druid","slug":"duplicate-column-name","errorCode":null,"errorMessage":"Duplicate column name: ","messagePattern":"Duplicate column name: ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/catalog/model/TableDefn.java","lineNumber":101,"sourceCode":"   * Validate a table spec using the table, field and column definitions defined\n   * here. The column definitions validate the type of each property value using\n   * the object mapper.\n   */\n  public void validate(ResolvedTable table)\n  {\n    validate(table.properties(), table.jsonMapper());\n    validateColumns(table.spec().columns());\n  }\n\n  public void validateColumns(List<ColumnSpec> columns)\n  {\n    if (columns == null) {\n      return;\n    }\n    Set<String> names = new HashSet<>();\n    for (ColumnSpec colSpec : columns) {\n      if (!names.add(colSpec.name())) {\n        throw new IAE(\"Duplicate column name: \" + colSpec.name());\n      }\n      colSpec.validate();\n      validateColumn(colSpec);\n    }\n  }\n\n  /**\n   * Table-specific validation of a column spec. Override for table definitions\n   * that need table-specific validation rules.\n   * <p>\n   * A column declared without a type is legal (the type is resolved from the physical schema, the ingestion query, or\n   * the input format), but a declared type must parse to a Druid type, otherwise we would silently substitute STRING\n   * for the unrecognized declaration. This runs at catalog write time only: reads never validate, so tables stored\n   * before this rule keep resolving (though editing them surfaces the invalid type). {@link Columns#druidType} maps\n   * {@code __time} to LONG regardless of the declared type, which {@link ColumnSpec#validate} already restricts to\n   * LONG or untyped.\n   */\n  protected void validateColumn(ColumnSpec colSpec)","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/catalog/model/TableDefn.java#L83-L119","documentation":"Druid's catalog table validation rejects a table spec whose column list contains two columns with the same name. TableDefn.validateColumns() iterates the columns and, if a name is already seen in the HashSet, throws IAE. Column names within a table must be unique to keep the column index map well-defined.","triggerScenarios":"Calling validate(), applyUpdateColumns(), or merge() on a TableSpec whose columns list contains two ColumnSpec entries with the identical name.","commonSituations":"Hand-editing a table spec JSON and duplicating a column; a column-update payload that re-adds an existing column name instead of replacing it; programmatic spec generation that appends columns without deduplication.","solutions":["Remove or rename the duplicate column so all column names in the spec are unique","Review the spec JSON (or update payload) and find which column name appears more than once","If updating an existing column, send the updated column in the update list with the same name (merge replaces it) rather than duplicating it in the base spec"],"exampleFix":"// before\n\"columns\": [{\"name\": \"ts\", \"type\": \"long\"}, {\"name\": \"ts\", \"type\": \"string\"}]\n// after\n\"columns\": [{\"name\": \"ts\", \"type\": \"long\"}, {\"name\": \"ts_str\", \"type\": \"string\"}]","handlingStrategy":"validation","validationCode":"Set<String> seen = new HashSet<>();\nfor (ColumnSpec c : spec.columns()) {\n  if (!seen.add(c.name())) { throw new IllegalArgumentException(\"duplicate column: \" + c.name()); }\n}","typeGuard":"boolean hasUniqueColumns(List<ColumnSpec> cols) {\n  return cols.stream().map(ColumnSpec::name).filter(Objects::nonNull).distinct().count() == cols.size();\n}","tryCatchPattern":"try { resolvedTable.validate(); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith(\"Duplicate column name\")) { /* fix spec */ } else { throw e; } }","preventionTips":["Deduplicate columns by name before building the spec","Treat column updates as replacements keyed by name, never appends of same-named columns","Validate spec JSON against a schema that enforces unique column names"],"tags":["validation","catalog","duplicate-column"],"backgroundTag":"schema-validation-failed","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}