quickwit-oss/quickwit · error
fields and default_field cannot be both set in `query_string
Error message
fields and default_field cannot be both set in `query_string` queries
What it means
In QueryStringQuery::convert_to_query_ast, the Elastic-compatible `query_string` query rejects requests that supply both `default_field` (single field) and `fields` (list of fields). These two options are alternative ways to scope the search, so setting both is ambiguous and is treated as an invalid request. Either omit one, or use only `fields` with a single-element list.
Source
Thrown at quickwit/quickwit-query/src/elastic_query_dsl/query_string_query.rs:46
/// We do not support JSON field either.
///
/// Note that following elastic, we do not support "string" and require an array here.
#[serde(default)]
fields: Option<Vec<String>>,
#[serde(default)]
default_field: Option<String>,
#[serde(default)]
default_operator: BooleanOperand,
#[serde(default)]
boost: Option<NotNaNf32>,
#[serde(default)]
lenient: LeniencyBool,
}
impl ConvertibleToQueryAst for QueryStringQuery {
fn convert_to_query_ast(self) -> anyhow::Result<crate::query_ast::QueryAst> {
if self.default_field.is_some() && self.fields.is_some() {
anyhow::bail!("fields and default_field cannot be both set in `query_string` queries");
}
let default_fields: Option<Vec<String>> = self
.default_field
.map(|default_field| vec![default_field])
.or(self.fields);
let user_text_query = UserInputQuery {
user_text: self.query,
default_fields,
default_operator: self.default_operator,
lenient: self.lenient,
};
Ok(user_text_query.into())
}
}
#[cfg(test)]
mod tests {
use crate::BooleanOperand;View on GitHub (pinned to a39730c5cd)
Solutions
- Remove `default_field` and keep only `fields` (list) when targeting multiple fields.
- Remove `fields` and keep only `default_field` when targeting a single field.
- If a single field is intended, move it into `fields` as a one-element list and drop `default_field`.
- Check client/library defaults that may inject `default_field` automatically.
Example fix
// before
{"query_string": {"query": "error", "default_field": "message", "fields": ["message", "level"]}}
// after
{"query_string": {"query": "error", "fields": ["message", "level"]}} Defensive patterns
Strategy: validation
Validate before calling
if qs.default_field.is_some() && qs.fields.is_some() {
return Err("query_string: provide either default_field or fields, not both");
} Try / catch
match parse_and_build(query) {
Err(e) if e.to_string().contains("cannot be both set") => {
// retry with fields only
}
r => r?,
} Prevention
- Pick one scoping style: fields for multi-field, default_field for single-field.
- Inspect client library defaults that inject default_field automatically.
- Validate query JSON payloads before submission in your API layer.
When it happens
Trigger: Calling convert_to_query_ast (e.g. via the query_string DSL or REST API with query_string queries) when both `default_field` and `fields` are set to Some, such as `{"query_string": {"query": "foo", "default_field": "body", "fields": ["title", "body"]}}`.
Common situations: Mixing Elasticsearch client libraries that set `default_field` by default while the user also passes `fields`; copying ES examples that use both; migrating from simple single-field queries to multi-field queries without removing the old `default_field` parameter.
Related errors
- both gt and gte are set
- both lt and lte are set
- failed to parse host: `{host}`
- failed to parse address `{}`: hostname is invalid
- index ID pattern `{pattern}` is invalid: patterns must not c
AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08).
Data as JSON: /api/errors/bfc2a2f9e2d0b30d.
Report an issue: GitHub.