apache/druid · error · IllegalArgumentException
Detected conflicting prefixes in join clauses: [%s, %s]
Error message
Detected conflicting prefixes in join clauses: [%s, %s]
What it means
The same validator also rejects prefix shadowing: one prefix that is a strict prefix-of another (e.g. 'l1.' and 'l1.x.'). Since a longer prefix's columns would also match the shorter one, column references become ambiguous and Druid throws this IllegalArgumentException.
Source
Thrown at processing/src/main/java/org/apache/druid/segment/join/JoinPrefixUtils.java:96
*
* @param prefixes A mutable list containing the prefixes to check. This list will be sorted by descending
* string length.
*/
public static void checkPrefixesForDuplicatesAndShadowing(
final List<String> prefixes
)
{
// this is a naive approach that assumes we'll typically handle only a small number of prefixes
prefixes.sort(DESCENDING_LENGTH_STRING_COMPARATOR);
for (int i = 0; i < prefixes.size(); i++) {
String prefix = prefixes.get(i);
for (int k = i + 1; k < prefixes.size(); k++) {
String otherPrefix = prefixes.get(k);
if (prefix.equals(otherPrefix)) {
throw new IAE("Detected duplicate prefix in join clauses: [%s]", prefix);
}
if (isPrefixedBy(prefix, otherPrefix)) {
throw new IAE("Detected conflicting prefixes in join clauses: [%s, %s]", prefix, otherPrefix);
}
}
}
}
}
View on GitHub (pinned to 9b90983fd2)
Solutions
- Change one prefix so no prefix is a prefix of another (use non-overlapping namespaces like l1., l2.)
- Use distinct, non-nested naming for every joinable table in the query
- If generated, update the prefix allocator to guarantee no shadowing
Example fix
// before prefixes: ["l1.", "l1.x."] // after prefixes: ["l1.", "l2."]
Defensive patterns
Strategy: validation
Validate before calling
for (int i = 0; i < prefixes.size(); i++)
for (int k = i + 1; k < prefixes.size(); k++)
if (prefixes.get(i).startsWith(prefixes.get(k)) || prefixes.get(k).startsWith(prefixes.get(i)))
throw new IllegalArgumentException("shadowing prefixes"); Try / catch
try { checkPrefixes(...); } catch (IAE e) { /* pick new, non-overlapping prefixes and retry planning */ } Prevention
- Use fixed-width, non-nested prefix namespaces (l1., l2., ...)
- Never derive a child join prefix from a parent prefix string
- Validate prefixes in tests for every stacked-join query shape
When it happens
Trigger: checkPrefixesForDuplicatesAndShadowing receives prefixes where one startsWith the other but they are not equal, e.g. ['l1.', 'l1.x.'] sorted descending, so isPrefixedBy(prefix, otherPrefix) is true.
Common situations: Nested/stacked joins where a sub-join's prefix accidentally begins with a parent join's prefix; manually chosen prefixes with overlapping namespaces.
Related errors
- Detected duplicate prefix in join clauses: [%s]
- maxStringBytes must be greater than 0
- maxStringBytes must be greater than 0
- Column[%s] does not start with prefix[%s]
- Multiple joinable factories are valid for table[%s]
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/bb0e608ceb12fe5e.
Report an issue: GitHub.