jaegertracing/jaeger · error
span_ids exceeds maximum limit: requested %d, max allowed %d
Error message
span_ids exceeds maximum limit: requested %d, max allowed %d
What it means
The get_span_details handler enforces a configured cap (h.maxSpanDetailsPerRequest) on how many span_ids may be requested at once. buildQuery rejects requests exceeding it with this formatted message, which includes both the requested and allowed counts, before any backend query is made.
Source
Thrown at cmd/jaeger/internal/extension/jaegerquery/internal/mcptools/internal/handlers/get_span_details.go:136
return nil, output, nil
}
// buildQuery converts GetSpanDetailsInput to querysvc.GetTraceParams and returns
// the requested span IDs in canonical lowercase hex form for the lookup set.
func (h *getSpanDetailsHandler) buildQuery(input types.GetSpanDetailsInput) (querysvc.GetTraceParams, []string, error) {
// Validate input
if input.TraceID == "" {
return querysvc.GetTraceParams{}, nil, errors.New("trace_id is required")
}
if len(input.SpanIDs) == 0 {
return querysvc.GetTraceParams{}, nil, errors.New("span_ids is required and must not be empty")
}
// Validate span count against configured limit
if len(input.SpanIDs) > h.maxSpanDetailsPerRequest {
return querysvc.GetTraceParams{}, nil, fmt.Errorf(
"span_ids exceeds maximum limit: requested %d, max allowed %d",
len(input.SpanIDs),
h.maxSpanDetailsPerRequest,
)
}
traceID, err := parseTraceID(input.TraceID)
if err != nil {
return querysvc.GetTraceParams{}, nil, fmt.Errorf("invalid trace_id: %w", err)
}
// Validate every span_id up front so a malformed value fails fast instead of
// triggering a backend query that can never match a real span ID. Collect the
// canonical lowercase hex form so the lookup set agrees with the ID the trace
// iterator emits regardless of the request's casing.
canonicalSpanIDs := make([]string, 0, len(input.SpanIDs))
for _, spanIDStr := range input.SpanIDs {
spanID, err := parseSpanID(spanIDStr)View on GitHub (pinned to 806f444784)
Solutions
- Reduce span_ids to the configured maximum (the error states both numbers).
- Chunk the lookup into multiple requests, each within the limit.
- Request only the specific spans of interest rather than all spans.
- If the default limit is genuinely too low for your workflow, raise maxSpanDetailsPerRequest in the jaeger-query MCP extension configuration.
Example fix
// before SpanIDs: allSpans // 250 ids, limit 100 // after SpanIDs: allSpans[:100] // chunk 1 of 3; send remaining ids in follow-up requests
Defensive patterns
Strategy: validation
Validate before calling
const maxSpanDetailsPerRequest = 100 // must match h.maxSpanDetailsPerRequest
func withinSpanLimit(spanIDs []string) bool {
return len(spanIDs) <= maxSpanDetailsPerRequest
} Try / catch
out, _, err := handler.Handle(ctx, req, input)
if err != nil && strings.Contains(err.Error(), "span_ids exceeds maximum limit") {
for chunk := range slices.Chunk(input.SpanIDs, maxSpanDetailsPerRequest) {
input.SpanIDs = chunk
out, _, err = handler.Handle(ctx, req, input)
}
} Prevention
- Chunk span ID lists to the configured limit before calling.
- Request only the spans you actually need.
- Read the limit value from the error message rather than assuming it.
- If you routinely hit the cap, raise maxSpanDetailsPerRequest server-side deliberately.
When it happens
Trigger: Calling the get_span_details MCP tool with input.SpanIDs containing more entries than maxSpanDetailsPerRequest, e.g. 200 span IDs when the limit is 100.
Common situations: Batch scripts expanding a large trace's full span list into one request; agents copying every span ID found in an earlier response instead of a focused subset; a lowered server-side limit after a config change.
Related errors
- trace_id is required
- start_time must be before end_time
- trace_id is required
- span_ids is required and must not be empty
- span ID must not be all zero
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/b1c59a589991660a.
Report an issue: GitHub.