apache/druid · error · IllegalStateException
Currently only single segment datasources are supported for…
Error message
Currently only single segment datasources are supported for broadcast joins, dataSource[%s] has multiple segments. Reingest the data so that it is entirely contained within a single segment to use in JOIN queries.
What it means
Broadcast (lookup-style) joins in Druid require the right-hand datasource to be contained in exactly one segment, since the whole table must be materialized in memory on each node. When Iterators.getOnlyElement sees more than one segment, the IllegalArgumentException is translated into this ISE instructing reingestion into a single segment.
Solutions
- Reingest the datasource with partitioning that produces a single segment (e.g. partition by nothing / maxTotalRows large enough).
- Compact the datasource so all rows are in one segment before joining.
- Use a hash/equi-join against a different joinable source (e.g. a lookup) instead of a multi-segment broadcast table.
Example fix
// before: join against datasource 'dim' with 5 segments JOIN fact ON fact.dimId = dim.id // after: reingest/compact 'dim' into 1 segment (tuningConfig maxTotalRows >= row count), then join
Defensive patterns
Strategy: validation
Validate before calling
// query-time guard: ensure broadcast side has one segment
if (dataSource instanceof TableDataSource && getSegmentCount(((TableDataSource) dataSource).getName()) > 1) {
throw new IllegalStateException("Broadcast join requires single-segment datasource");
} Prevention
- Compact broadcast-joined datasources to a single segment before querying.
- Prefer lookup tables or hash joins for large dimension tables.
When it happens
Trigger: Running a JOIN query whose broadcast side is a datasource with 2+ segments — commonly after incremental ingestion created many segments for the joined table.
Common situations: Joining against a time-partitioned datasource that has grown beyond one segment; enabling compaction too late; using broadcast joins in dev on datasources loaded over multiple batches.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- BroadcastTablesTooLarge
- Column[ ] is not a valid column for segment[ ]
- Caching is not supported. Check `isCacheable` before…
- Cannot build hash-join matcher on non-equi-join condition
- Cannot build hash-join matcher on non-key-based condition
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/4ca5af46e3906be5.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/main/java/org/apache/druid/segment/join/BroadcastTableJoinableFactory.java:85
if (!condition.canHashJoin()) {
return Optional.empty();
}
return getOnlyIndexedTable(dataSource).filter(IndexedTable::isCacheable).map(IndexedTable::computeCacheKey);
}
private Optional<ReferenceCountedIndexedTableProvider> getOnlyIndexedTable(DataSource dataSource)
{
GlobalTableDataSource broadcastDataSource = (GlobalTableDataSource) dataSource;
return segmentManager.getIndexedTables(broadcastDataSource).flatMap(tables -> {
Iterator<ReferenceCountedIndexedTableProvider> tableIterator = tables.iterator();
if (!tableIterator.hasNext()) {
return Optional.empty();
}
try {
return Optional.of(Iterators.getOnlyElement(tableIterator));
}
catch (IllegalArgumentException iae) {
throw new ISE(
"Currently only single segment datasources are supported for broadcast joins, dataSource[%s] has multiple segments. Reingest the data so that it is entirely contained within a single segment to use in JOIN queries.",
broadcastDataSource.getName()
);
}
});
}
}
View on GitHub (pinned to 9b90983fd2)