apache/druid · error · QueryUnsupportedException
Restricted data source
Error message
Restricted data source [%s] with policy [%s] is not supported
What it means
PreJoinableClause.maybeUnwrapRestrictedDataSource unwraps a RestrictedDataSource only when its policy is NoRestrictionPolicy; any actual restriction policy on a joinable clause is unsupported in this code path and raises QueryUnsupportedException. Druid does not yet support applying row-level restriction policies inside join subqueries.
Solutions
- Restructure the query so the restricted table is the base (outer) data source, not the join clause
- Remove the restriction policy from the joined data source
- Filter the joinable subquery explicitly with WHERE clauses instead of a policy
- Upgrade Druid if newer versions add support for restricted joinables
Example fix
// before: restricted table used as join subquery SELECT ... FROM main JOIN restricted_t ON ... // after: pre-filter explicitly SELECT ... FROM main JOIN (SELECT * FROM t WHERE tenant_id = 'x') AS rt ON ...
Defensive patterns
Strategy: try-catch
Validate before calling
if (dataSource instanceof RestrictedDataSource
&& !(((RestrictedDataSource) dataSource).getPolicy() instanceof NoRestrictionPolicy)) {
throw new UnsupportedOperationException("cannot use restricted datasource inside a joinable clause");
} Type guard
boolean isUnrestricted(DataSource ds) {
return !(ds instanceof RestrictedDataSource)
|| ((RestrictedDataSource) ds).getPolicy() instanceof NoRestrictionPolicy;
} Try / catch
try {
runQuery(query);
} catch (QueryUnsupportedException e) {
if (e.getMessage().contains("Restricted data source")) {
// rewrite: move filtering into an explicit WHERE subquery
runQuery(rewriteWithoutRestrictedJoin(query));
} else throw e;
} Prevention
- Keep restricted (row-level-security) tables as the base data source of a query
- Use explicit WHERE filters in join subqueries instead of policies
When it happens
Trigger: A SQL/native query with a join whose joinable clause's data source carries a RestrictedDataSource with a non-NoRestriction policy (e.g. user-based row filtering).
Common situations: Combining row-level security policies with JOIN queries; nesting a restricted table as a subquery inside a join in SQL.
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
- 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
- Cannot handle constant condition
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/090f4c824ea7601b.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/query/planning/PreJoinableClause.java:83
public DataSource getDataSource()
{
return dataSource;
}
/**
* If the data source is a {@link RestrictedDataSource} with a {@link NoRestrictionPolicy}, unwraps it to a table and return.
* <p>
* This is a temporary workaround to allow the planner to work with {@link RestrictedDataSource} as the right-side join.
*/
public DataSource maybeUnwrapRestrictedDataSource()
{
if (dataSource instanceof RestrictedDataSource) {
RestrictedDataSource restricted = (RestrictedDataSource) dataSource;
if (restricted.getPolicy() instanceof NoRestrictionPolicy) {
return restricted.getBase();
} else {
throw new QueryUnsupportedException(StringUtils.format(
"Restricted data source [%s] with policy [%s] is not supported",
restricted.getBase(),
restricted.getPolicy()
));
}
} else {
return dataSource;
}
}
public JoinType getJoinType()
{
return joinType;
}
public JoinConditionAnalysis getCondition()
{
return condition;View on GitHub (pinned to 9b90983fd2)