jaegertracing/jaeger · error

SearchDepth must not be greater than %d

Error message

SearchDepth must not be greater than %d

What it means

toProtoQuery converts tracestore.TraceQueryParams to the api_v3 protobuf TraceQueryParameters, whose SearchDepth field is int32. If the caller's SearchDepth exceeds math.MaxInt32 the conversion would silently truncate, so the function rejects it with 'SearchDepth must not be greater than 2147483647'.

Source

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

	})
	if err != nil {
		return operations, err
	}
	for _, operation := range res.Operations {
		operations = append(operations, tracestore.Operation{
			Name:     operation.Name,
			SpanKind: operation.SpanKind,
		})
	}
	return operations, nil
}

// toProtoQuery renders a search as the api_v3 request the query service reads, which is the
// only shape the e2e tests can send: they drive jaeger over the wire rather than calling a
// 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
	}

View on GitHub (pinned to 806f444784)

Solutions

  1. Clamp or unset SearchDepth before calling search: use a sane value (e.g. 100) or leave zero when you don't need depth limiting
  2. Set an explicit bounded SearchDepth in the TraceQueryParams your tests/config construct
  3. If this comes from a shared default constant, convert the sentinel to MaxInt32 before invoking the api_v3 reader

Example fix

// before
query := tracestore.TraceQueryParams{SearchDepth: math.MaxUint64}
// after
if query.SearchDepth > math.MaxInt32 {
    query.SearchDepth = math.MaxInt32
}
Defensive patterns

Strategy: validation

Validate before calling

if query.SearchDepth > math.MaxInt32 {
    query.SearchDepth = math.MaxInt32 // clamp sentinel/default values
}

Try / catch

q, err := toProtoQuery(params)
if err != nil {
    if strings.Contains(err.Error(), "SearchDepth must not") {
        params.SearchDepth = 100
        q, err = toProtoQuery(params)
    }
    if err != nil { return err }
}

Prevention

When it happens

Trigger: Calling search through the api_v3 traceReader with a TraceQueryParams whose SearchDepth is set to a value greater than math.MaxInt32 (practically only an unset/default sentinel like math.MaxUint64 or a huge default).

Common situations: Passing a default SearchDepth sentinel (e.g. math.MaxUint64 used by tracestore to mean 'no limit') directly into the api_v3 reader without clamping it first.

Related errors


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