jaegertracing/jaeger · error
this storage backend cannot serve this query filter
Error message
this storage backend cannot serve this query filter
What it means
ErrFilterUnsupported signals that a tracestore Reader cannot evaluate a query filter because the filter requires capabilities (a stored built-in field of a level, or an operator on certain references) the backend did not declare via FilterCapabilities. It is returned instead of approximating the answer, so callers never silently receive a narrower result presented as the whole answer (RFC 0005 §7).
Source
Thrown at internal/storage/v2/api/tracestore/capabilities.go:21
package tracestore
import (
"errors"
"slices"
expression "github.com/jaegertracing/jaeger-idl/query/expression/v1"
)
// ErrFilterUnsupported is returned for a well-formed query filter that the storage cannot
// serve — a level it does not index, an operator it has not implemented, or a boolean
// structure a flat index cannot evaluate (RFC 0005 §7). The query is refused rather than
// approximated, so a caller never reads a narrower answer as the whole one. The query
// service returns it for the limits a Reader declared through FilterCapabilities, and a
// Reader returns it for the ones that declaration is too coarse to express — a built-in
// field of a level it serves but does not store, or an operator it serves on some
// references and not others.
var ErrFilterUnsupported = errors.New("this storage backend cannot serve this query filter")
// ErrFilterInvalid is returned for a query filter whose value does not fit the field it
// compares — the kind of mistake a structural check cannot catch, because the filter AST
// deliberately does not carry types (RFC 0005 §6.1).
var ErrFilterInvalid = errors.New("invalid query filter")
// SearchCapabilities describes how a Reader's search methods behave where backends
// differ: which TraceQueryParams fields may be omitted, which are honored exactly
// rather than approximated, and which combinations a backend cannot serve. Its zero
// value is the least capable reader, so a field added here leaves every existing
// implementation declaring the new capability unsupported.
//
// Fields to expect over time, each of which is a real divergence today:
//
// - Whether SearchDepth is an exact limit or a hint. jaeger.api_v3's
// TraceQueryParameters warns of search_depth that "some implementations might not
// support precise limits", so a caller cannot tell whether a short result set means
// that there are no more matches or that the backend stopped early.View on GitHub (pinned to 806f444784)
Solutions
- Inspect the Reader's FilterCapabilities and remove or replace the unsupported field/operator in the query filter
- Use an operator that the backend supports for that reference type
- Check the filter AST against RFC 0005 §7 semantics — the backend refuses rather than approximates, so narrow the query to what is declared supported
- Switch to a storage backend that supports the filter, or store the field the filter references
Example fix
// before
query := tracestore.OperationQuery{Filter: filter.Eq(field.SpanName, value)} // backend doesn't store span_name
// after
caps := reader.FilterCapabilities()
if !caps.Supports(field.SpanName) { /* use a supported field or error out in the caller */ } Defensive patterns
Strategy: validation
Validate before calling
caps := reader.FilterCapabilities()
if !caps.SupportsFilter(field, op) {
return fmt.Errorf("query skipped: backend does not support filter on %s", field)
} Type guard
func filterSupported(r tracestore.Reader, f filter.Condition) bool {
caps := r.FilterCapabilities()
return caps.Supports(f.Field) && caps.SupportsOperator(f.Field, f.Op)
} Try / catch
deps, err := reader.Search(ctx, q)
if errors.Is(err, tracestore.ErrFilterUnsupported) {
// fall back to a supported query or surface a clear 4xx to the user
} Prevention
- Check FilterCapabilities before building filters
- Avoid hardcoding filter fields/operators that vary by backend
- Add tests that run your query set against each backend's declared capabilities
When it happens
Trigger: Calling Reader search/query APIs with a filter condition referencing a field the backend serves but does not store, or using an operator (e.g. negation, regex, range) the backend supports on some references but not the one queried; the query service also returns it for limits declared through FilterCapabilities.
Common situations: Switching storage backends (e.g. from Elasticsearch to ClickHouse) while keeping hardcoded filters; using filter operators not supported by a flat-index backend; code written against one Reader being pointed at a less capable Reader.
Related errors
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/df26f19448738f23.
Report an issue: GitHub.