apache/druid · error · IllegalArgumentException
A table definition must include a table spec.
Error message
A table definition must include a table spec.
What it means
A TableMetadata carries the table's TableSpec (properties and columns). validate() requires this spec to be present; a null spec means the table object has no definition content, so validation throws IAE after the id checks pass.
Solutions
- Attach a valid TableSpec to the TableMetadata before validating
- Check why the spec was not deserialized (missing JSON field, wrong payload)
- If the metadata is intentionally a stub, skip validate() until a spec is available
Example fix
// before
TableMetadata md = new TableMetadata(id, null);
md.validate();
// after
TableMetadata md = new TableMetadata(id, new TableSpec("datasource", props, columns));
md.validate(); Defensive patterns
Strategy: type-guard
Validate before calling
if (md == null || md.spec() == null) {
throw new IllegalArgumentException("table metadata requires a spec");
} Type guard
boolean hasSpec(TableMetadata md) {
return md != null && md.spec() != null;
} Try / catch
try { md.validate(); } catch (IllegalArgumentException e) { if (e.getMessage().contains("must include a table spec")) { /* fetch or build the spec */ } else { throw e; } } Prevention
- Make spec a required constructor argument where possible
- Check API payloads always include the spec object
- Only validate fully-assembled TableMetadata objects
When it happens
Trigger: Calling TableMetadata.validate() where the spec field is null — metadata created without a spec, or deserialization of a metadata record that lacked the spec object.
Common situations: Creating TableMetadata placeholders before the spec is fetched; API payloads that return metadata rows without the embedded spec JSON; accidental null passed to the constructor.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- An external HTTP table with a URI must also provide the…
- An external HTTP table with a URI must also provide the…
- An external S3 table with a format must also provide the…
- CatalogException.validationError(e) (wraps…
- CatalogException.validationError(e) (wraps…
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/a922e05c62098b00.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/main/java/org/apache/druid/catalog/model/TableMetadata.java:270
public TableSpec spec()
{
return spec;
}
/**
* Syntactic validation of a table object. Validates only that which
* can be checked from this table object.
*/
public void validate()
{
if (Strings.isNullOrEmpty(id.schema())) {
throw new IAE("Database schema is required");
}
if (Strings.isNullOrEmpty(id.name())) {
throw new IAE("Table name is required");
}
if (spec == null) {
throw new IAE("A table definition must include a table spec.");
}
}
@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)