apache/druid · error · IllegalArgumentException
[%s] column must have type [%s] or no type. Found [%s]
Error message
[%s] column must have type [%s] or no type. Found [%s]
What it means
ColumnSpec.validate enforces that the special __time column has Druid type LONG (or no explicit type). Assigning any other dataType (e.g. string, double) to the time column is invalid because the primary time column is internally stored as a long epoch millis value.
Source
Thrown at server/src/main/java/org/apache/druid/catalog/model/ColumnSpec.java:108
{
return dataType;
}
@JsonProperty("properties")
@JsonInclude(Include.NON_EMPTY)
public Map<String, Object> properties()
{
return properties;
}
public void validate()
{
if (Strings.isNullOrEmpty(name)) {
throw new IAE("Column name is required");
}
if (Columns.isTimeColumn(name)) {
if (dataType != null && !Columns.LONG.equalsIgnoreCase(dataType)) {
throw new IAE(
"[%s] column must have type [%s] or no type. Found [%s]",
name,
Columns.LONG,
dataType
);
}
}
// Validate type in the next PR
}
/**
* Merges an updated version of this column with an existing version.
* <p>
* The name cannot be changed (it is what links the existing column and the
* update). The SQL type will be that provided in the update, if non-null, else
* the original type. Properties are merged using standard rules: those in the
* update take precedence. Null values in the update remove the existing property,
* non-null values update the property. Any properties in the update but not inView on GitHub (pinned to 9b90983fd2)
Solutions
- Set the __time column dataType to "long", or remove the dataType property entirely.
- Express timestamp formatting in the ingestion timestampSpec instead of typing the column as timestamp.
- Search the spec for case mismatches — "LONG" is accepted case-insensitively, but "timestamp" is not.
Example fix
// before
{"name": "__time", "dataType": "timestamp"}
// after
{"name": "__time", "dataType": "long"} Defensive patterns
Strategy: validation
Validate before calling
if ("__time".equals(spec.getName()) && spec.getDataType() != null
&& !"long".equalsIgnoreCase(spec.getDataType())) {
throw new IllegalArgumentException("__time dataType must be long or omitted");
} Type guard
boolean isValidTimeColumnType(ColumnSpec spec) {
return !Columns.isTimeColumn(spec.getName())
|| spec.getDataType() == null
|| Columns.LONG.equalsIgnoreCase(spec.getDataType());
} Try / catch
try { spec.validate(); } catch (IllegalArgumentException e) { // correct the __time type to long or drop dataType } Prevention
- Never declare __time as timestamp/string/date; use long or omit dataType.
- Configure timestamp parsing via timestampSpec, not column type.
- Add a spec-level lint rule that checks time-column typing.
When it happens
Trigger: Calling validate() (directly or via mergeColumn/testColumnSpec) on a ColumnSpec named __time whose dataType is set to anything other than "long" (case-insensitive), e.g. "string" or "timestamp".
Common situations: Users coming from SQL intuition set the __time column type to "timestamp" or "date"; schema import from another system carries over a DATETIME/TIMESTAMP type for the time column.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Value [%s] is not valid for property [%s], expected type [%s
- Column 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
- The %s property cannot be provided when the %s property is s
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/9cfaac7f5fd5877c.
Report an issue: GitHub.