SigNoz/signoz · warning

CodeNotFound

CodeNotFound

Error message

no spans found matching the specified criteria

What it means

Thrown by GetSpanPercentile in the spanpercentile module when the underlying query returns zero result series. The transform step treats an empty query result as 'not found' rather than returning an empty response. This typically means no spans matched the supplied trace/span filters or time range.

Source

Thrown at pkg/modules/spanpercentile/implspanpercentile/module.go:55

	if err != nil {
		return nil, err
	}

	if err := queryRangeRequest.Validate(); err != nil {
		return nil, err
	}

	result, err := m.querier.QueryRange(ctx, orgID, queryRangeRequest)
	if err != nil {
		return nil, err
	}

	return transformToSpanPercentileResponse(result)
}

func transformToSpanPercentileResponse(queryResult *qbtypes.QueryRangeResponse) (*spanpercentiletypes.SpanPercentileResponse, error) {
	if len(queryResult.Data.Results) == 0 {
		return nil, errors.New(errors.TypeNotFound, errors.CodeNotFound, "no spans found matching the specified criteria")
	}

	scalarData, ok := queryResult.Data.Results[0].(*qbtypes.ScalarData)
	if !ok {
		return nil, errors.New(errors.TypeInternal, errors.CodeInternal, "unexpected result type")
	}

	if len(scalarData.Data) == 0 {
		return nil, errors.New(errors.TypeNotFound, errors.CodeNotFound, "no spans found matching the specified criteria")
	}

	row := scalarData.Data[0]

	columnMap := make(map[string]int)
	for i, col := range scalarData.Columns {
		columnMap[col.Name] = i
	}

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Verify the service name, operation, and time range actually have ingested spans
  2. Widen the start/end time window and re-issue the request
  3. Check the span filters for typos or wrong casing
  4. Confirm the ClickHouse/query backend has data for that period

Example fix

// before
resp, err := module.GetSpanPercentile(ctx, spanID, startTime, endTime)
// after
// ensure time range covers the span; verify span exists via trace API first
resp, err := module.GetSpanPercentile(ctx, spanID, startTime.Add(-time.Minute), endTime.Add(time.Minute))
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify spans exist for the window before requesting percentiles
exists, err := spanStore.HasSpans(ctx, filter, start, end)
if err != nil || !exists {
    return fmt.Errorf("no spans in window: %w", err)
}

Type guard

func isNotFoundErr(err error) bool {
    var e *errors.Error
    return errors.As(err, &e) && e.Code == errors.CodeNotFound
}

Try / catch

resp, err := module.GetSpanPercentile(ctx, spanID, start, end)
if err != nil {
    if isNotFoundErr(err) {
        // degrade gracefully: show "no data" in UI
        return emptyPercentile(), nil
    }
    return nil, err
}

Prevention

When it happens

Trigger: Calling GetSpanPercentile with filters (service name, operation, trace ID, time range) that match no spans in the query backend; querying a time window before data was ingested.

Common situations: Wrong or misspelled service/operation name in filters, timestamps in the wrong format/timezone, querying an environment with no traffic, or insufficiently broad start/end times.

Related errors


AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28). Data as JSON: /api/errors/0becb8fdd695dce7. Report an issue: GitHub.