apache/druid · error · CatalogException

CatalogException.validationError(e) (wraps…

Error message

CatalogException.validationError(e) (wraps IAE/DruidException validation message)

What it means

TableEditor.applyUpdateColumns merges column updates into the existing spec and validates the revised column list with defn.validateColumns(revised); failures (IAE/DruidException) are wrapped in CatalogException.validationError(e). This guards against updates that would leave the table's columns invalid (duplicates, type changes violating rules, etc.).

Solutions

  1. Fix the offending column update per the wrapped validation message.
  2. Fetch the latest table spec first so merges are applied on a current column list.
  3. Split large column updates into smaller changes to isolate the invalid one.
  4. Re-run validation locally by constructing the TableDefn and calling validateColumns on the merged list.

Example fix

// before: update adds a column named 'ts' when 'ts' already exists
// after: rename new column to 'ts2' or drop/replace the existing one
Defensive patterns

Strategy: try-catch

Validate before calling

// Re-apply the merge locally and validate before submitting
List<ColumnSpec> merged = defn.mergeColumns(existingSpec.columns(), updates);
defn.validateColumns(merged); // throws before the server does

Try / catch

try { editor.updateColumns(tableId, updates); }
catch (CatalogException e) { if (e.isValidation()) { refreshSpecAndRetryWithFixedUpdates(e); } else { throw e; } }

Prevention

When it happens

Trigger: Submitting an updateColumns operation to the table editor where the merged column list fails definition-level validation, e.g. renaming to an existing column name, changing a column type in a disallowed way, or dropping a required column.

Common situations: Concurrent edits based on stale column lists; batch updates combining several column changes where one is invalid; tooling that generates column diffs with conflicting names.

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/a6d0a6069aed9209. Report an issue: GitHub.

Appendix: source

Thrown at extensions-core/druid-catalog/src/main/java/org/apache/druid/catalog/http/TableEditor.java:317

    return catalog.tables().updateColumns(
        id,
        table -> applyUpdateColumns(table, updates)
    );
  }

  private TableSpec applyUpdateColumns(
      final TableMetadata table,
      final List<ColumnSpec> updates
  ) throws CatalogException
  {
    final TableSpec existingSpec = table.spec();
    final TableDefn defn = resolveDefn(existingSpec.type());
    final List<ColumnSpec> revised = defn.mergeColumns(existingSpec.columns(), updates);
    try {
      defn.validateColumns(revised);
    }
    catch (IAE | DruidException e) {
      throw CatalogException.validationError(e);
    }
    return existingSpec.withColumns(revised);
  }

  private long moveColumn(MoveColumn moveColumn) throws CatalogException
  {
    if (Strings.isNullOrEmpty(moveColumn.column)) {
      throw CatalogException.badRequest("A column name is required");
    }
    if (moveColumn.where == null) {
      throw CatalogException.badRequest("A target location is required");
    }
    if ((moveColumn.where == Position.BEFORE || moveColumn.where == Position.AFTER) && Strings.isNullOrEmpty(moveColumn.anchor)) {
      throw CatalogException.badRequest("A anchor column is required for BEFORE or AFTER");
    }
    return catalog.tables().updateColumns(
        id,
        table -> applyMoveColumn(table, moveColumn)

View on GitHub (pinned to 9b90983fd2)