apache/druid · error · IllegalArgumentException
Table type is required
Error message
Table type is required
What it means
TableSpec.validate() checks that every table spec declares its type, since the type selects the table definition that interprets the spec. An empty or null type makes the spec uninterpretable, so validate() throws IAE. Note that update specs intentionally may omit type; validation is meant to run on merged, complete specs.
Source
Thrown at server/src/main/java/org/apache/druid/catalog/model/TableSpec.java:103
return properties;
}
@JsonProperty("columns")
@JsonInclude(Include.NON_NULL)
public List<ColumnSpec> columns()
{
return columns;
}
/**
* Validate the final spec. Updates use this same class, but allow
* the spec to be partial (and thus inconsistent). Validation should
* be done on the merged result, not on the updates themselves.
*/
public void validate()
{
if (Strings.isNullOrEmpty(type)) {
throw new IAE("Table type is required");
}
}
@Override
public String toString()
{
return CatalogUtils.toString(this);
}
@Override
public boolean equals(Object o)
{
if (o == this) {
return true;
}
if (o == null || o.getClass() != getClass()) {
return false;
}View on GitHub (pinned to 9b90983fd2)
Solutions
- Set the type field on the spec before validating
- If validating an update, merge it with the base spec first and validate the merged TableSpec instead
- Check the source JSON includes the "type" property
Example fix
// before TableSpec update = new TableSpec(null, props, null); update.validate(); // throws // after TableSpec merged = base.merge(base, update, mapper); merged.validate(); // validate the merged, complete spec
Defensive patterns
Strategy: validation
Validate before calling
if (Strings.isNullOrEmpty(spec.type())) {
throw new IllegalArgumentException("spec.type must be set before validate()");
} Type guard
boolean isCompleteSpec(TableSpec spec) {
return spec != null && spec.type() != null && !spec.type().isEmpty();
} Try / catch
try { spec.validate(); } catch (IllegalArgumentException e) { if (e.getMessage().equals("Table type is required")) { /* merge with base or set type */ } else { throw e; } } Prevention
- Validate only complete (merged) specs, not update fragments
- Always set type when constructing standalone specs
- Enforce the type field in spec JSON at deserialization
When it happens
Trigger: Calling TableSpec.validate() on a spec whose type field is null/empty — e.g. a partial update spec validated directly instead of being merged first, or JSON missing the "type" field.
Common situations: Validating update payloads (which are allowed to have null type) instead of the merged result; hand-written spec JSON omitting "type"; deserialization binding failures.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Column name is required
- Database schema is required
- Table name is required
- An external S3 table with a format must also provide the cor
- Provide either the %s property, or one of the S3 input sourc
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/58b2d0aa2d1e5a96.
Report an issue: GitHub.