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
- Verify the service name, operation, and time range actually have ingested spans
- Widen the start/end time window and re-issue the request
- Check the span filters for typos or wrong casing
- 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
- Validate time range and filters before querying
- Confirm the trace/span exists via a trace lookup first
- Treat CodeNotFound from percentile APIs as empty-state, not a failure
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.