quickwit-oss/quickwit · error

failed to parse range query date format. {err}

Error message

failed to parse range query date format. {err}

What it means

When a range query specifies a date format (JsonLiteral::String interpreted as a Java date-time format), convert_to_query_ast builds a StrptimeParser from it via from_java_datetime_format. This error is raised when that Java format string itself cannot be parsed into a valid strptime pattern.

Source

Thrown at quickwit/quickwit-query/src/elastic_query_dsl/range_query.rs:94

                gte = Some(from_val);
            } else {
                gt = Some(from_val);
            }
        }
        if let Some(to_val) = to
            && lt.is_none()
            && lte.is_none()
        {
            if include_upper.unwrap_or(true) {
                lte = Some(to_val);
            } else {
                lt = Some(to_val);
            }
        }

        let (gt, gte, lt, lte) = if let Some(JsonLiteral::String(java_date_format)) = format {
            let parser = StrptimeParser::from_java_datetime_format(&java_date_format)
                .map_err(|err| anyhow::anyhow!("failed to parse range query date format. {err}"))?;
            (
                gt.map(|v| parse_and_convert(v, &parser)).transpose()?,
                gte.map(|v| parse_and_convert(v, &parser)).transpose()?,
                lt.map(|v| parse_and_convert(v, &parser)).transpose()?,
                lte.map(|v| parse_and_convert(v, &parser)).transpose()?,
            )
        } else {
            (gt, gte, lt, lte)
        };

        let range_query_ast = crate::query_ast::RangeQuery {
            field,
            lower_bound: match (gt, gte) {
                (Some(_gt), Some(_gte)) => {
                    anyhow::bail!("both gt and gte are set")
                }
                (Some(gt), None) => Bound::Excluded(gt),
                (None, Some(gte)) => Bound::Included(gte),

View on GitHub (pinned to a39730c5cd)

Solutions

  1. Fix the format string to a supported Java datetime pattern (e.g. "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
  2. Remove the format field and use RFC3339/ISO8601 date literals instead (the default)
  3. Check the error's inner message for which directive failed and consult StrptimeParser::from_java_datetime_format docs for supported directives
  4. Test the format string in isolation before embedding it in the query

Example fix

// before
{"range": {"ts": {"gte": "2024-01-01", "format": "yyyy-MM-ddd HH:mm"}}}
// after
{"range": {"ts": {"gte": "2024-01-01", "format": "yyyy-MM-dd HH:mm"}}}
Defensive patterns

Strategy: validation

Validate before calling

if let Some(JsonLiteral::String(fmt)) = &format {
    StrptimeParser::from_java_datetime_format(fmt).map_err(|e| format!("invalid format '{fmt}': {e}"))?;
}

Try / catch

try {
    build_range_query(json)
} catch (e) {
    if (e.message.includes('failed to parse range query date format')) { /* drop format or fix pattern */ }
    throw e;
}

Prevention

When it happens

Trigger: Sending an ES-compatible range query with a "format" field containing an invalid or unsupported Java datetime pattern (e.g. malformed pattern like "yyyy-MM-ddd" or unsupported directives) to the query DSL parser.

Common situations: Copy-pasted Elasticsearch date formats with directives Quickwit's parser doesn't support; typos in format strings; mixing strftime and Java format syntaxes.

Understand the failure class

Related errors


AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08). Data as JSON: /api/errors/1b86ff649959b331. Report an issue: GitHub.