jaegertracing/jaeger · error

start and End Time must be set

Error message

start and End Time must be set

What it means

ErrStartAndEndTimeNotSet is a sentinel error returned by validateQuery when neither StartTimeMin nor StartTimeMax is provided in a time-based trace query. The reader requires an explicit time window to construct the Elasticsearch range filter, so it refuses the query when both bounds are absent.

Source

Thrown at internal/storage/v2/elasticsearch/tracestore/core/reader.go:65

	errorTag               = "error"

	defaultSearchDepth = 100

	DawnOfTimeSpanAge = time.Hour * 24 * 365 * 50
)

var (
	// ErrStartTimeMinGreaterThanMax occurs when start time min is above start time max
	ErrStartTimeMinGreaterThanMax = errors.New("start Time Minimum is above Maximum")

	// ErrDurationMinGreaterThanMax occurs when duration min is above duration max
	ErrDurationMinGreaterThanMax = errors.New("duration Minimum is above Maximum")

	// ErrMalformedRequestObject occurs when a request object is nil
	ErrMalformedRequestObject = errors.New("malformed request object")

	// ErrStartAndEndTimeNotSet occurs when start time and end time are not set
	ErrStartAndEndTimeNotSet = errors.New("start and End Time must be set")

	// ErrUnableToFindTraceIDAggregation occurs when an aggregation query for TraceIDs fail.
	ErrUnableToFindTraceIDAggregation = errors.New("could not find aggregation of traceIDs")

	defaultMaxDuration = model.DurationAsMicroseconds(time.Hour * 24)

	objectTagFieldList = []string{objectTagsField, objectProcessTagsField}

	nestedTagFieldList = []string{nestedTagsField, nestedProcessTagsField, nestedLogFieldsField}

	_ Reader = (*SpanReader)(nil) // check API conformance
)

// Time-range design (referenced as "timeRangeDesign" in comments below):
//
// There are two read operations with different time-range semantics:
//
//  1. FindTraceIDs: the user always supplies [StartTimeMin, StartTimeMax]. No adjustment needed.

View on GitHub (pinned to 806f444784)

Solutions

  1. Set both StartTimeMin and StartTimeMax to an explicit window (e.g. last 24h) before querying.
  2. Default the window in your caller: StartTimeMax=now, StartTimeMin=now-lookback.
  3. If you need unbounded queries, iterate over bounded windows instead.

Example fix

// before
params := v2api.TraceQueryParameters{ServiceName: "svc"} // times unset
// after
now := time.Now()
params := v2api.TraceQueryParameters{ServiceName: "svc", StartTimeMin: now.Add(-24 * time.Hour), StartTimeMax: now}
Defensive patterns

Strategy: validation

Validate before calling

func ensureTimeWindow(p *api.TraceQueryParameters, lookback time.Duration) {
    if p.StartTimeMin.IsZero() || p.StartTimeMax.IsZero() {
        p.StartTimeMax = time.Now()
        p.StartTimeMin = p.StartTimeMax.Add(-lookback)
    }
}

Try / catch

ids, err := reader.FindTraceIDs(ctx, query)
if errors.Is(err, core.ErrStartAndEndTimeNotSet) {
    return http.StatusBadRequest // time window required
}

Prevention

When it happens

Trigger: Calling reader.FindTraceIDs/FindTraces with TraceQueryParameters where both StartTimeMin and StartTimeMax are zero values (unset), typically when intending to query 'all traces'. validateQuery returns this error instead of issuing an unbounded scan.

Common situations: Leaving time fields at their zero value when copying the query struct; UIs that omit defaults; assuming an empty time range means 'no time filter' when the API actually requires explicit bounds.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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