jaegertracing/jaeger · error · ErrFilterUnsupported

%w: it does not index the %q level

Error message

%w: it does not index the %q level

What it means

EnsureSupported also checks that the Reader indexes the data level (trace, span, or span attribute) referenced by each AttributeRef in the filter. If the Reader's capability set excludes that level, it returns ErrFilterUnsupported with the level name.

Source

Thrown at internal/storage/v2/api/tracestore/admission.go:95

		var level expression.Level
		switch term := arg.(type) {
		case *expression.Call:
			if err := c.EnsureSupported(term); err != nil {
				return err
			}
			continue
		case *expression.AttributeRef:
			level = term.Level
		case *expression.FieldRef:
			level = term.Level
		case *expression.NestedRef:
			level = term.Level
		default:
			// A constant carries nothing a Reader has to support.
			continue
		}
		if !c.SupportsLevel(level) {
			return fmt.Errorf("%w: it does not index the %q level", ErrFilterUnsupported, level)
		}
	}
	return nil
}

View on GitHub (pinned to 806f444784)

Solutions

  1. Rewrite the predicate to a level the Reader supports (e.g. match as a span attribute instead of trace level).
  2. Drop predicates on non-indexed levels.
  3. Pre-validate with legacy/reader capabilities via EnsureSupported before querying.

Example fix

// before
expr := expression.Eq(expression.TraceAttribute("x"), "y") // reader lacks trace level
// after
expr := expression.Eq(expression.SpanAttribute("x"), "y") // indexed level
Defensive patterns

Strategy: validation

Validate before calling

caps := reader.FilterCapabilities()
expression.WalkRefs(filter, func(ref *expression.AttributeRef) {
  if !caps.SupportsLevel(ref.Level) {
    panic(fmt.Sprintf("level %q not indexed by reader", ref.Level))
  }
})

Try / catch

if err := reader.FindTraces(ctx, traces, q); err != nil {
  if errors.Is(err, tracestore.ErrFilterUnsupported) && strings.Contains(err.Error(), "level") {
    filter = lowerToSpanLevel(filter)
  }
}

Prevention

When it happens

Trigger: Passing a filter that references, say, a trace-level attribute to a Reader that only supports span-level or span-attribute-level predicates (SupportsLevel false for that Level), at any nesting depth of the expression.

Common situations: Filters authored for one storage backend (which indexes a level) run against another (which does not, e.g. some v2 adapters over legacy stores); programmatic filter builders that emit attributes at levels the user never chose.

Related errors


AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01). Data as JSON: /api/errors/95350ce96af9e99b. Report an issue: GitHub.