{"record":{"id":"9d5c00ac83591d5c","repo":"apache/druid","slug":"cannot-accept-both-findcolumnsfromheader-and-ha","errorCode":null,"errorMessage":"Cannot accept both [findColumnsFromHeader] and [hasHeaderRow]","messagePattern":"Cannot accept both \\[findColumnsFromHeader\\] and \\[hasHeaderRow\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/data/input/impl/FlatTextInputFormat.java","lineNumber":67,"sourceCode":"  private final boolean tryParseNumbers;\n\n  FlatTextInputFormat(\n      @Nullable List<String> columns,\n      @Nullable String listDelimiter,\n      String delimiter,\n      @Nullable Boolean hasHeaderRow,\n      @Nullable Boolean findColumnsFromHeader,\n      int skipHeaderRows,\n      @Nullable Boolean tryParseNumbers\n  )\n  {\n    this.columns = columns == null ? Collections.emptyList() : columns;\n    this.listDelimiter = listDelimiter;\n    this.delimiter = Preconditions.checkNotNull(delimiter, \"delimiter\");\n    if (columns == null || columns.isEmpty()) {\n      if (hasHeaderRow != null && findColumnsFromHeader != null) {\n        // User provided both hasHeaderRow and findColumnsFromHeader.\n        throw new IAE(\"Cannot accept both [findColumnsFromHeader] and [hasHeaderRow]\");\n      } else if (hasHeaderRow == null && findColumnsFromHeader == null) {\n        // User provided neither columns, nor one of the header-related parameters.\n        throw new IAE(\"Either [columns] or [findColumnsFromHeader] must be set\");\n      } else {\n        // User provided one of hasHeaderRow or findColumnsFromHeader. Take the one they provided.\n        this.findColumnsFromHeader = hasHeaderRow != null ? hasHeaderRow : findColumnsFromHeader;\n      }\n    } else {\n      this.findColumnsFromHeader = findColumnsFromHeader == null ? false : findColumnsFromHeader;\n    }\n    this.skipHeaderRows = skipHeaderRows;\n    Preconditions.checkArgument(\n        !delimiter.equals(listDelimiter),\n        \"Cannot have same delimiter and list delimiter of [%s]\",\n        delimiter\n    );\n    this.tryParseNumbers = tryParseNumbers == null ? false : tryParseNumbers;\n","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/data/input/impl/FlatTextInputFormat.java#L49-L85","documentation":"FlatTextInputFormat's constructor rejects configurations that supply both the legacy 'hasHeaderRow' flag and the newer 'findColumnsFromHeader' flag, because their combination is ambiguous. Only one header-detection mechanism may be given.","triggerScenarios":"Constructing FlatTextInputFormat (or submitting a JSON ingestion spec with a csv/tsv inputFormat) where 'columns' is null/empty AND both 'hasHeaderRow' and 'findColumnsFromHeader' are non-null.","commonSituations":"Upgrading specs written for older Druid versions (which used hasHeaderRow) and adding findColumnsFromHeader without removing the old field; copy-pasting examples that mix the two options.","solutions":["Remove 'hasHeaderRow' and keep only 'findColumnsFromHeader' (current API)","Or remove 'findColumnsFromHeader' if intentionally using the legacy 'hasHeaderRow'","Alternatively specify an explicit 'columns' list, which bypasses both flags"],"exampleFix":"// before\n{\"type\":\"csv\",\"hasHeaderRow\":true,\"findColumnsFromHeader\":true}\n// after\n{\"type\":\"csv\",\"findColumnsFromHeader\":true}","handlingStrategy":"validation","validationCode":"// Before submitting the spec\nMap<String,Object> fmt = (Map<String,Object>) spec.get(\"inputFormat\");\nif (fmt.get(\"hasHeaderRow\") != null && fmt.get(\"findColumnsFromHeader\") != null) {\n    fmt.remove(\"hasHeaderRow\"); // prefer the modern flag\n}","typeGuard":null,"tryCatchPattern":"try { new FlatTextInputFormat(columns, listDelimiter, delimiter, hasHeaderRow, findColumnsFromHeader, skipHeaderRows); } catch (IAE e) { /* strip one header flag and retry */ }","preventionTips":["Use only 'findColumnsFromHeader' in new specs; treat 'hasHeaderRow' as deprecated","Run spec JSON through a schema validator before submission","Grep spec templates for mixed header flags during upgrades"],"tags":["configuration","csv","api-migration"],"backgroundTag":"mutually-exclusive-flags","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}