{"record":{"id":"bf51ab438f7a5608","repo":"jaegertracing/jaeger","slug":"please-provide-at-least-one-service-name","errorCode":null,"errorMessage":"please provide at least one service name","messagePattern":"please provide at least one service name","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"cmd/jaeger/internal/extension/jaegerquery/internal/query_parser.go","lineNumber":106,"sourceCode":"//\n//\tquery ::= services , [ '&' optionalParams ]\n//\toptionalParams := param | param '&' optionalParams\n//\tparam ::=  groupByOperation | endTs | lookback | step | ratePer | spanKinds\n//\tservices ::= service | service '&' services\n//\tservice ::= 'service=' strValue\n//\tgroupByOperation ::= 'groupByOperation=' boolValue\n//\tendTs ::= 'endTs=' intValue in unix milliseconds\n//\tlookback ::= 'lookback=' intValue duration in milliseconds\n//\tstep ::= 'step=' intValue duration in milliseconds\n//\tratePer ::= 'ratePer=' intValue duration in milliseconds\n//\tspanKinds ::= spanKind | spanKind '&' spanKinds\n//\tspanKind ::= 'spanKind=' spanKindType\n//\tspanKindType ::= \"unspecified\" | \"internal\" | \"server\" | \"client\" | \"producer\" | \"consumer\"\nfunc (p *queryParser) parseMetricsQueryParams(r *http.Request) (bqp metricstore.BaseQueryParameters, err error) {\n\tquery := r.URL.Query()\n\tservices, ok := query[serviceParam]\n\tif !ok {\n\t\treturn bqp, newParseError(errors.New(\"please provide at least one service name\"), serviceParam)\n\t}\n\tbqp.ServiceNames = services\n\n\tbqp.GroupByOperation, err = parseBool(r, groupByOperationParam)\n\tif err != nil {\n\t\treturn bqp, err\n\t}\n\tbqp.SpanKinds, err = parseSpanKinds(r, spanKindParam, defaultMetricsSpanKinds)\n\tif err != nil {\n\t\treturn bqp, err\n\t}\n\tendTs, err := p.parseTime(r, endTsParam, time.Millisecond)\n\tif err != nil {\n\t\treturn bqp, err\n\t}\n\tparser := newDurationUnitsParser(time.Millisecond)\n\tlookback, err := parseDuration(r, lookbackParam, parser, defaultMetricsQueryLookbackDuration)\n\tif err != nil {","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/cmd/jaeger/internal/extension/jaegerquery/internal/query_parser.go#L88-L124","documentation":"The metrics query parser builds metricstore.BaseQueryParameters from the HTTP query string. Jaeger's metrics endpoints require at least one service name; when the `service` query parameter is absent entirely, parseMetricsQueryParams returns this parse error wrapped with the offending parameter name. Empty-but-present values are accepted here — it is the missing key itself that triggers the error.","triggerScenarios":"GET/POST to a Jaeger metrics endpoint (/api/metrics/...) without a `service` query parameter, e.g. GET /api/metrics/minsecs or /api/metrics/latency with only params like quantile/endTs.","commonSituations":"Hand-crafted curl calls to metrics endpoints omitting service=; dashboards whose service dropdown initializes empty; API clients copied from trace-search examples where service is optional but metrics endpoints require it.","solutions":["Add a service query parameter to the request, e.g. ?service=checkout (repeatable: service=a&service=b).","If the service name comes from a UI variable, ensure it is populated/defaulted before rendering the request.","Check the endpoint path — if you meant to browse traces without a service, use the trace search endpoint, not metrics."],"exampleFix":"// before\nGET /api/metrics/minqty?endTs=1700000000000&spanKind=server\n// after\nGET /api/metrics/minqty?service=payments&endTs=1700000000000&spanKind=server","handlingStrategy":"validation","validationCode":"u, _ := url.Parse(req.URL)\nif len(u.Query()[\"service\"]) == 0 {\n    return errors.New(\"metrics request must include at least one service query parameter\")\n}","typeGuard":null,"tryCatchPattern":"resp, err := http.Get(metricsURL)\nif err != nil || resp.StatusCode == http.StatusBadRequest {\n    body, _ := io.ReadAll(resp.Body)\n    if strings.Contains(string(body), \"service name\") {\n        return fmt.Errorf(\"metrics query needs ?service=... ; got %s\", body)\n    }\n    return err\n}","preventionTips":["Build metrics URLs from a helper that always injects the service parameter.","Default the service in dashboards to a known-good value instead of leaving it blank.","Check the Jaeger API docs per endpoint — metrics endpoints are stricter than trace search."],"tags":["http-api","metrics","missing-param"],"backgroundTag":"missing-required-argument","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}