apache/druid · error · IllegalArgumentException
Column[%s] does not start with prefix[%s]
Error message
Column[%s] does not start with prefix[%s]
What it means
JoinPrefixUtils.unprefix strips a join-table prefix (e.g. 'l1.') from a column name, but only if the column actually starts with that prefix. If it does not, Druid throws this IllegalArgumentException because returning the original name would silently mis-map columns in a join.
Source
Thrown at processing/src/main/java/org/apache/druid/segment/join/JoinPrefixUtils.java:72
}
public static boolean isPrefixedBy(final String columnName, final String prefix)
{
return columnName.length() > prefix.length() && columnName.startsWith(prefix);
}
/**
* Removes the prefix on {@code columnName}. Must only be called if the column name is actually prefixed; i.e.,
* if {@link #isPrefixedBy(String, String)} would return true on the same arguments.
*
* @throws IllegalArgumentException if columnName does not start with prefix
*/
public static String unprefix(final String columnName, final String prefix)
{
if (isPrefixedBy(columnName, prefix)) {
return columnName.substring(prefix.length());
} else {
throw new IAE("Column[%s] does not start with prefix[%s]", columnName, prefix);
}
}
/**
* Check if any prefixes in the provided list duplicate or shadow each other.
*
* @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++) {View on GitHub (pinned to 9b90983fd2)
Solutions
- Check the join clause and the prefix declared on the joinable dataSource match the column name being unprefixed
- Remove or correct the prefix parameter so it equals the actual prefix of the column name
- Ensure all right-side columns in equi conditions are prefixed consistently when building the native query
Example fix
// before
String name = JoinPrefixUtils.unprefix("country_code", "l1."); // IAE
// after
String name = JoinPrefixUtils.unprefix("l1.country_code", "l1."); Defensive patterns
Strategy: validation
Validate before calling
if (!columnName.startsWith(prefix)) { throw new IllegalArgumentException("Column " + columnName + " lacks prefix " + prefix); }
String bare = JoinPrefixUtils.unprefix(columnName, prefix); Type guard
boolean isPrefixed(String col, String prefix) { return col != null && prefix != null && col.startsWith(prefix); } Try / catch
try { return JoinPrefixUtils.unprefix(columnName, prefix); } catch (IllegalArgumentException e) { log.error("prefix mismatch: {} vs {}", columnName, prefix); throw e; } Prevention
- Always derive the prefix from the same join clause object used to build column names
- Unit-test join clause construction so prefixes and column names come from one source
- Assert isPrefixedBy(columnName, prefix) before unprefixing in custom code
When it happens
Trigger: Calling JoinPrefixUtils.unprefix(columnName, prefix) where columnName does not begin with prefix; typically reached when join column names in a join clause were computed with a different prefix than the one used during unprefixing.
Common situations: Misconfigured join condition column names in a native join (prefix mismatch between the join clause and the table prefix), SQL plan translation bugs where right-column identifiers were not prefixed, or user-supplied native JSON joins where the equated column name lacks the declared prefix.
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
- Detected duplicate prefix in join clauses: [%s]
- Detected conflicting prefixes in join clauses: [%s, %s]
- Multiple joinable factories are valid for table[%s]
- Joining against a multi-value dimension is not supported.
- Joining against a ARRAY columns is not supported.
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/b9fe0602dbbe6cc4.
Report an issue: GitHub.