apache/druid · error · CatalogException

BAD_STATE

BAD_STATE

Error message

Table %s has an invalid type [%s]

What it means

TableEditor.resolveDefn() looks up the TableDefn class registered for a table's type string. A null result means the stored table definition references a type unknown to the current catalog registry — an internal inconsistency, so it throws a CatalogException with BAD_STATE code and HTTP 500. This should be impossible for valid data and usually indicates corrupt metadata or a missing type registration (e.g. after an extension providing the type was removed).

Source

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

    final TableDefn defn = resolveDefn(existingSpec.type());
    final Map<String, Object> revised = defn.mergeProperties(
        existingSpec.properties(),
        updates
    );
    try {
      defn.validate(revised, catalog.jsonMapper());
    }
    catch (IAE e) {
      throw CatalogException.badRequest(e.getMessage());
    }
    return existingSpec.withProperties(revised);
  }

  private TableDefn resolveDefn(String tableType) throws CatalogException
  {
    TableDefn defn = catalog.tableRegistry().tableDefnFor(tableType);
    if (defn == null) {
      throw new CatalogException(
          CatalogException.BAD_STATE,
          Response.Status.INTERNAL_SERVER_ERROR,
          "Table %s has an invalid type [%s]",
          id.sqlName(),
          tableType
      );
    }
    return defn;
  }

  private long updateColumns(final List<ColumnSpec> updates) throws CatalogException
  {
    if (CollectionUtils.isNullOrEmpty(updates)) {
      return 0;
    }
    return catalog.tables().updateColumns(
        id,
        table -> applyUpdateColumns(table, updates)

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Check the type value in the error against tables registered in the running Druid version (registry/tableDefnFor) — fix the table definition's type to a valid registered type.
  2. Re-enable/install the extension or module that registers the missing TableDefn type and restart Druid.
  3. If the table definition is corrupt or obsolete, delete or repair it in the metadata store through a valid catalog resource call or migration script.

Example fix

// before
PATCH .../catalog/tables/druid.foo  {"type":"streamV9"} // unregistered type

// after
PATCH .../catalog/tables/druid.foo  {"type":"datasource"}
Defensive patterns

Strategy: validation

Validate before calling

const table = await fetch(`/druid-ext/v1/catalog/tables/${tableId}`).then(r => r.json());
const KNOWN_TYPES = new Set(['datasource']);
function hasValidType(t) { return KNOWN_TYPES.has(t.type); }
if (!hasValidType(table)) throw new Error('unknown table type: ' + table.type);

Try / catch

try {
  const defn = editor.defn();
} catch (CatalogException e) {
  if (CatalogException.BAD_STATE.equals(e.getCode())) {
    // reload table, verify extension providing the type is loaded, or repair/delete the table
  }
}

Prevention

When it happens

Trigger: Loading/editing a table (via defn()) whose stored 'type' field has no matching TableDefn in the registry, e.g. type added by an extension that is no longer loaded, or a hand-edited/damaged table definition in metadata storage.

Common situations: Upgrading or downgrading Druid where the catalog no longer registers a table type; uninstalling an extension that defined custom table types while catalog metadata still references them; manual edits to metadata-store entries introducing an invalid type string.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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