apache/druid · error · IllegalArgumentException
virtualColumn name[ ] not allowed
Error message
virtualColumn name[%s] not allowed
What it means
Virtual column output names must not collide with the special __time column, since __time is always present in segments and shadowing it would be ambiguous. fromIterable throws IAE if any virtual column's output name equals ColumnHolder.TIME_COLUMN_NAME.
Solutions
- Rename the virtual column to something like "v_time" and reference that name in the query
- Compute time transforms via the __time column with an extraction/expression in selectors instead of shadowing it
- Update query-generation code to reject "__time" as a virtual column name
Example fix
// before
new ExpressionVirtualColumn("__time", "timestamp_shift(__time, 'P1D')", ValueType.LONG, macros)
// after
new ExpressionVirtualColumn("v_shifted_time", "timestamp_shift(__time, 'P1D')", ValueType.LONG, macros) Defensive patterns
Strategy: validation
Validate before calling
if (ColumnHolder.TIME_COLUMN_NAME.equals(vc.getOutputName())) {
throw new IllegalArgumentException("__time is reserved and cannot be a virtual column name");
} Try / catch
try {
VirtualColumns.fromIterable(cols);
} catch (IAE e) {
log.error(e, "Virtual column name conflicts with __time");
} Prevention
- Treat __time as reserved in query generation
- Use prefixed names (v_) for virtual columns
- Reject reserved names in query builders
When it happens
Trigger: Constructing VirtualColumns with a virtual column whose getOutputName() is "__time" — e.g. an expression column intentionally named __time in a native query.
Common situations: Custom queries trying to override __time with a computed timestamp; generated queries colliding names; users unaware __time is reserved.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Duplicate virtualColumn name
- Empty or null virtualColumn name
- Cannot handle datasource
- Cannot handle subquery
- Cannot have a null/empty columns
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/1e91bac6c0038af8.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/segment/VirtualColumns.java:116
return fromIterable(virtualColumns);
}
public static VirtualColumns create(VirtualColumn... virtualColumns)
{
return create(Arrays.asList(virtualColumns));
}
public static VirtualColumns fromIterable(Iterable<VirtualColumn> virtualColumns)
{
Map<String, VirtualColumn> withDotSupport = new HashMap<>();
Map<String, VirtualColumn> withoutDotSupport = new HashMap<>();
for (VirtualColumn vc : virtualColumns) {
if (Strings.isNullOrEmpty(vc.getOutputName())) {
throw new IAE("Empty or null virtualColumn name");
}
if (vc.getOutputName().equals(ColumnHolder.TIME_COLUMN_NAME)) {
throw new IAE("virtualColumn name[%s] not allowed", vc.getOutputName());
}
if (withDotSupport.containsKey(vc.getOutputName()) || withoutDotSupport.containsKey(vc.getOutputName())) {
throw new IAE("Duplicate virtualColumn name[%s]", vc.getOutputName());
}
if (vc.usesDotNotation()) {
withDotSupport.put(vc.getOutputName(), vc);
} else {
withoutDotSupport.put(vc.getOutputName(), vc);
}
}
return new VirtualColumns(ImmutableList.copyOf(virtualColumns), withDotSupport, withoutDotSupport);
}
public static VirtualColumns nullToEmpty(@Nullable VirtualColumns virtualColumns)
{
return virtualColumns == null ? EMPTY : virtualColumns;View on GitHub (pinned to 9b90983fd2)