jaegertracing/jaeger · error

cannot encode the query filter

Error message

cannot encode the query filter: %w

What it means

When the query carries a filter expression, toProtoQuery encodes it to protobuf via expressionproto.ToProto. If the expression cannot be represented as a proto filter (unsupported operator, malformed value type), the error is wrapped as 'cannot encode the query filter' and the search fails.

Solutions

  1. Inspect the wrapped error to identify which part of the expression failed to encode
  2. Simplify or rewrite the filter using operators/value types supported by the api_v3 filter proto
  3. If the filter came from user input, validate it against the supported expression grammar before issuing the query

Example fix

// before
filter, _ := expr.NewComparison("tags.x", expr.Equals, someCustomType{})
// after
filter, _ := expr.NewComparison("tags.x", expr.Equals, "string-value")
Defensive patterns

Strategy: validation

Validate before calling

// validate filter before querying
ast, err := expr.Parse(filterStr)
if err != nil { return err }
if err := expr.ValidateSupported(ast, expressionproto.SupportedOperators()); err != nil {
    return fmt.Errorf("filter uses unsupported constructs: %w", err)
}

Try / catch

q, err := toProtoQuery(params)
if err != nil && strings.Contains(err.Error(), "cannot encode the query filter") {
    log.Warn("dropping unsupported filter, querying unfiltered", zap.Error(err))
    params.Filter = nil
    q, err = toProtoQuery(params)
}

Prevention

When it happens

Trigger: A tracestore search is issued with query.Filter set to an expression that expressionproto.ToProto cannot serialize — e.g. an operator or value type with no proto representation.

Common situations: Tests or callers constructing filter expressions programmatically with operators unsupported by the api_v3 filter proto; mixing value types the proto schema does not accept; version skew between the expression library and the proto definition.

Related errors


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

Appendix: source

Thrown at cmd/jaeger/internal/integration/trace_reader.go:145

// Reader, so a predicate this function drops is one no e2e test can exercise.
func toProtoQuery(query tracestore.TraceQueryParams) (*api_v3.TraceQueryParameters, error) {
	if query.SearchDepth > math.MaxInt32 {
		return nil, fmt.Errorf("SearchDepth must not be greater than %d", math.MaxInt32)
	}
	protoQuery := &api_v3.TraceQueryParameters{
		ServiceName:   query.ServiceName,
		OperationName: query.OperationName,
		Attributes:    jptrace.PcommonMapToPlainMap(query.Attributes),
		StartTimeMin:  query.StartTimeMin,
		StartTimeMax:  query.StartTimeMax,
		DurationMin:   query.DurationMin,
		DurationMax:   query.DurationMax,
		SearchDepth:   int32(query.SearchDepth), //nolint:gosec // G115 - bounds checked above
	}
	if query.Filter != nil {
		filter, err := expressionproto.ToProto(query.Filter)
		if err != nil {
			return nil, fmt.Errorf("cannot encode the query filter: %w", err)
		}
		protoQuery.Filter = filter
	}
	return protoQuery, nil
}

func (r *traceReader) FindTraces(
	ctx context.Context,
	query tracestore.TraceQueryParams,
) iter.Seq2[[]ptrace.Traces, error] {
	return func(yield func([]ptrace.Traces, error) bool) {
		protoQuery, err := toProtoQuery(query)
		if err != nil {
			yield(nil, err)
			return
		}
		protoQuery.RawTraces = true
		stream, err := r.client.FindTraces(ctx, &api_v3.FindTracesRequest{Query: protoQuery})

View on GitHub (pinned to 806f444784)