apache/druid · error · BadQueryContextException
Expected key [%s] to be referring to one of the values [%s]
Error message
Expected key [%s] to be referring to one of the values [%s] of enum [%s], but got [%s]
What it means
Druid's QueryContexts.getAsEnum converts a query context value into an enum constant by upper-casing the value and calling Enum.valueOf. When the value does not name any constant of the target enum, the IllegalArgumentException from valueOf is rethrown as a BadQueryContextException listing the valid enum values. It exists so query context keys carrying enum-typed settings fail fast with an actionable message instead of silently misbehaving.
Source
Thrown at processing/src/main/java/org/apache/druid/query/QueryContexts.java:569
}
@Nullable
public static <E extends Enum<E>> E getAsEnum(String key, Object value, Class<E> clazz)
{
if (value == null) {
return null;
}
try {
if (value instanceof String) {
return Enum.valueOf(clazz, StringUtils.toUpperCase((String) value));
} else if (value instanceof Boolean) {
return Enum.valueOf(clazz, StringUtils.toUpperCase(String.valueOf(value)));
}
}
catch (IllegalArgumentException e) {
throw badValueException(
key,
StringUtils.format(
"referring to one of the values [%s] of enum [%s]",
Arrays.stream(clazz.getEnumConstants()).map(Enum::name).collect(
Collectors.joining(",")),
clazz.getSimpleName()
),
value
);
}
throw badTypeException(
key,
StringUtils.format("of type [%s]", clazz.getSimpleName()),
value
);
}
View on GitHub (pinned to 9b90983fd2)
Solutions
- Read the error message's list of valid values and set the context key to one of the listed enum constant names (case-insensitive).
- Check the Druid version's documentation for the specific context key; enum constants may differ across versions.
- If the value is computed dynamically, validate it against Enum.valueOf(clazz, value.toUpperCase()) before putting it in the query context.
Example fix
// before
query.setContextValue("vectorize", "yess");
// after
query.setContextValue("vectorize", "true"); Defensive patterns
Strategy: validation
Validate before calling
// Java
boolean valid = Arrays.stream(MyEnum.values()).anyMatch(e -> e.name().equalsIgnoreCase(value));
if (!valid) throw new IllegalArgumentException("context value must be one of " + Arrays.toString(MyEnum.values())); Type guard
static <E extends Enum<E>> boolean isEnumValue(Object v, Class<E> clazz) {
return (v instanceof String && Arrays.stream(clazz.getEnumConstants()).anyMatch(e -> e.name().equalsIgnoreCase((String) v)))
|| (v instanceof Boolean && Arrays.stream(clazz.getEnumConstants()).anyMatch(e -> e.name().equalsIgnoreCase(String.valueOf(v))));
} Try / catch
try {
query.addContext("vectorize", value);
} catch (BadQueryContextException e) {
log.error("Rejecting bad context value: {}", e.getMessage());
throw new IllegalArgumentException("Invalid enum context value", e);
} Prevention
- Whitelist context values against Enum.valueOf(...) before submitting queries.
- Use the query's typed context API instead of raw string maps.
- Pin context key names/values to a specific Druid version and re-check on upgrades.
When it happens
Trigger: Setting a query context key that is parsed as an enum (e.g. via QueryContexts.getEnum or context-aware query options) to a string or boolean that does not match any constant of the target enum class, such as context {"vectorize":"yess"} where the enum only has TRUE/FALSE or NONE.
Common situations: Typos in query context JSON submitted via SQL (SET clauses) or the native query API; copying context values from an older Druid version where an enum constant was renamed or removed; passing boolean-like strings ('yes'/'on') where only the enum's constant names are accepted.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- No such outputChannelMode[%s]
- %s is an unknown multi stage query mode. Acceptable modes: %
- Timeout [timeout] must be a non negative value, but was %d
- Per-segment timeout [timeoutPerSegmentQuery] must be a non n
- Expected key [%s] to be of type [%s], but got [%s]
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/100545b4fb41c644.
Report an issue: GitHub.