apache/druid · error · IllegalStateException
Transform name ' ' cannot be used twice
Error message
Transform name '%s' cannot be used twice
What it means
TransformSpec's constructor validates that all configured Transform objects have unique names, since transformed columns would otherwise collide ambiguously. If two transforms share a name, this ISE is thrown at spec construction — typically when deserializing an ingestion spec's transformSpec or a query's transformSpec from JSON.
Solutions
- Rename one of the duplicate transforms so each name in the transforms array is unique.
- If both transforms compute the same thing, delete the redundant entry and keep one.
- If you need both intermediate and final values, give the second transform a distinct name and reference the first by column name in its expression.
- Validate the spec JSON before submission (e.g. assert distinct transform names in your tooling).
Example fix
// before
"transforms": [
{"name": "ts", "expression": "timestamp_parse(raw_ts)"},
{"name": "ts", "expression": "format(raw_ts)"}
]
// after
"transforms": [
{"name": "ts", "expression": "timestamp_parse(raw_ts)"},
{"name": "ts_formatted", "expression": "format(raw_ts)"}
] Defensive patterns
Strategy: validation
Validate before calling
Set<String> names = new HashSet<>();
for (Transform t : transformSpec.getTransforms()) {
if (!names.add(t.getName())) {
throw new IllegalArgumentException("Duplicate transform name: " + t.getName());
}
} Prevention
- Use unique, descriptive names for every transform in a spec.
- When templating or merging specs, deduplicate transforms by name before submission.
- Add a pre-submit lint step in CI validating Druid ingestion spec JSON.
When it happens
Trigger: Building/submitting an ingestion task or native query whose transformSpec.transforms list contains two Transform entries with the same name.
Common situations: Copy-pasting a transform block in the ingestion spec and forgetting to rename it; programmatically generating transforms where a loop appends duplicate names; merging specs from templates that both define the same transform name.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Cannot simultaneously replace and append to existing…
- Could not transform dimension value for
- Could not transform value for
- Attempt to add row to swapped-out sink for segment
- Bloom filter aggregators are query-time only
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/c6a5c32dd714f875.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/segment/transform/TransformSpec.java:62
public static final TransformSpec NONE = new TransformSpec(null, null);
private final DimFilter filter;
private final List<Transform> transforms;
@JsonCreator
public TransformSpec(
@JsonProperty("filter") final DimFilter filter,
@JsonProperty("transforms") final List<Transform> transforms
)
{
this.filter = filter;
this.transforms = transforms == null ? ImmutableList.of() : transforms;
// Check for name collisions.
final Set<String> seen = new HashSet<>();
for (Transform transform : this.transforms) {
if (!seen.add(transform.getName())) {
throw new ISE("Transform name '%s' cannot be used twice", transform.getName());
}
}
}
@JsonProperty
@Nullable
public DimFilter getFilter()
{
return filter;
}
@JsonProperty
public List<Transform> getTransforms()
{
return transforms;
}
public InputSourceReader decorate(InputSourceReader reader)View on GitHub (pinned to 9b90983fd2)