apache/druid · error · IllegalArgumentException

If an external table provides columns, it must also provide…

Error message

If an external table provides columns, it must also provide a format

What it means

FormattedInputSourceDefn.validate requires that if an external table declares columns, it must also declare an input format. Columns cannot be interpreted without knowing the format of the underlying data, so a columns-without-format spec is invalid.

Solutions

  1. Add the format property (e.g. {"type":"csv",...}) to the input format map.
  2. Remove the column definitions if the format should be auto-detected instead.
  3. Provide both columns and format together in the spec.
  4. Re-save the table through the UI/console so both fields are populated.

Example fix

// before
{"columns":[{"name":"a","type":"bigint"}]}
// after
{"columns":[{"name":"a","type":"bigint"}],"inputFormat":{"type":"csv"}}
Defensive patterns

Strategy: validation

Validate before calling

boolean hasCols = spec.getColumns() != null && !spec.getColumns().isEmpty();
boolean hasFmt = spec.getInputFormat() != null;
if (hasCols && !hasFmt) throw new IllegalArgumentException("columns require an inputFormat");

Try / catch

try { saveExternalTable(spec); } catch (IAE e) { if (e.getMessage().contains("must also provide a format")) { spec.setInputFormat(defaultFormatFor(spec)); saveExternalTable(spec); } }

Prevention

When it happens

Trigger: Validating an external table where spec().columns() is non-empty but inputFormatMap is null; e.g. saving a formatted external table spec with a schema but no format property.

Common situations: Manually editing table JSON and deleting the format block while keeping columns; API clients that send partial updates dropping the format; templates that set columns but leave format unset.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/b0f9c92b8d82b339. Report an issue: GitHub.

Appendix: source

Thrown at server/src/main/java/org/apache/druid/catalog/model/table/FormattedInputSourceDefn.java:66

{
  public static final String FORMAT_PARAMETER = "format";

  private Map<String, InputFormatDefn> formats;

  @Override
  public void bind(TableDefnRegistry registry)
  {
    formats = registry.formats();
    super.bind(registry);
  }

  @Override
  public void validate(ResolvedExternalTable table)
  {
    final boolean hasColumns = !CollectionUtils.isNullOrEmpty(table.resolvedTable().spec().columns());
    final boolean hasFormat = table.inputFormatMap != null;
    if (hasColumns && !hasFormat) {
      throw new IAE("If an external table provides columns, it must also provide a format");
    }
    if (!hasColumns && hasFormat) {
      throw new IAE("If an external table provides a format, it must also provide columns");
    }
    super.validate(table);
  }

  @Override
  protected AdHocTableFunction defineAdHocTableFunction()
  {
    List<ParameterDefn> fullTableParams = adHocTableFnParameters();
    List<ParameterDefn> allParams = addFormatParameters(fullTableParams);
    return new AdHocTableFunction(allParams);
  }

  /**
   * Overridden by subclasses to provide the list of table function parameters for
   * this specific input format. This list is combined with parameters for input

View on GitHub (pinned to 9b90983fd2)