{"record":{"id":"0f3b0ba6c9dd92fa","repo":"jaegertracing/jaeger","slug":"this-storage-backend-requires-a-service-name-to-se","errorCode":null,"errorMessage":"this storage backend requires a service name to search; searching all services is not supported","messagePattern":"this storage backend requires a service name to search; searching all services is not supported","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"cmd/jaeger/internal/extension/jaegerquery/querysvc/service.go","lineNumber":32,"sourceCode":"\t\"go.opentelemetry.io/collector/pdata/ptrace\"\n\n\t\"github.com/jaegertracing/jaeger-idl/model/v1\"\n\texpression \"github.com/jaegertracing/jaeger-idl/query/expression/v1\"\n\t\"github.com/jaegertracing/jaeger/cmd/jaeger/internal/extension/jaegerquery/internal/adjuster\"\n\t\"github.com/jaegertracing/jaeger/components/extension/jaegerquery/queryinterceptor\"\n\t\"github.com/jaegertracing/jaeger/internal/jptrace\"\n\t\"github.com/jaegertracing/jaeger/internal/storage/v1/api/spanstore\"\n\t\"github.com/jaegertracing/jaeger/internal/storage/v2/api/depstore\"\n\t\"github.com/jaegertracing/jaeger/internal/storage/v2/api/tracestore\"\n)\n\nvar errNoArchiveSpanStorage = errors.New(\"archive span storage was not configured\")\n\n// ErrServiceNameRequired is returned for a search that omits the service name against a\n// backend whose reader does not accept one (RFC 0013 §3.3). It names the backend's\n// limitation rather than the missing field, because the same query is valid elsewhere.\n// The API layers map it to InvalidArgument / HTTP 400.\nvar ErrServiceNameRequired = errors.New(\n\t\"this storage backend requires a service name to search; searching all services is not supported\",\n)\n\n// QueryServiceOptions holds the configuration options for the query service.\ntype QueryServiceOptions struct {\n\t// ArchiveTraceReader is used to read archived traces from the storage.\n\tArchiveTraceReader tracestore.Reader\n\t// ArchiveTraceWriter is used to write traces to the archive storage.\n\tArchiveTraceWriter tracestore.Writer\n\t// MaxClockSkewAdjust is the maximum duration by which to adjust a span.\n\tMaxClockSkewAdjust time.Duration\n\t// MaxTraceSize is the maximum number of spans allowed per trace. A value of 0 (default) means unlimited.\n\t// If a trace has more spans than this limit, it will be truncated and a warning will be added.\n\tMaxTraceSize int\n\t// Interceptors are the query-interceptor extensions this deployment configured, in the order\n\t// it named them. The query service invokes their OnQuery around every trace search and their\n\t// OnResult around every batch of loaded traces. Most deployments configure none.\n\tInterceptors []queryinterceptor.Interceptor","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/cmd/jaeger/internal/extension/jaegerquery/querysvc/service.go#L14-L50","documentation":"ErrServiceNameRequired is returned by FindTraces when a search omits the service name while the configured storage backend's reader cannot search without one (RFC 0013 §3.3). The message names the backend's limitation rather than a missing field because the same query is valid against other backends. The API layers deliberately map it to HTTP 400 / gRPC InvalidArgument (it satisfies querysvc.IsBadRequest) so the caller knows to change the query.","triggerScenarios":"Calling the /api/traces search endpoint (or gRPC SpansQuery) without a `service` parameter against a backend whose reader rejects service-less searches; the service is only added by the caller, never defaulted by the service layer.","commonSituations":"'Search all services' UI dashboards pointed at a backend that requires a service; scripts that browse traces by time range alone; switching storage backends (e.g. to one with this limitation) and reusing old queries that omitted service.","solutions":["Add a service query parameter to the search request (e.g. ?service=frontend&...).","Enumerate services first via the /api/services endpoint and iterate searches per service instead of searching all services at once.","If service-less search is a hard requirement, switch to a storage backend whose reader supports it.","Ensure your API client treats this as a 400-class error (querysvc.IsBadRequest) and shows an actionable message, not a retryable 500."],"exampleFix":"// before\nGET /api/traces?limit=50  // no service, backend requires one\n// after\nservices := getServices(ctx) // GET /api/services\nGET /api/traces?service=frontend&limit=50","handlingStrategy":"validation","validationCode":"if service == \"\" {\n    return errors.New(\"this backend requires a service parameter for trace search\")\n}","typeGuard":"func isServiceNameRequired(err error) bool {\n    return errors.Is(err, querysvc.ErrServiceNameRequired) || querysvc.IsBadRequest(err) && strings.Contains(err.Error(), \"service name\")\n}","tryCatchPattern":"err := svc.FindTraces(ctx, q, onTrace)\nif err != nil {\n    if errors.Is(err, querysvc.ErrServiceNameRequired) {\n        return status.Error(codes.InvalidArgument, \"search requires ?service=... on this backend\")\n    }\n    return err\n}","preventionTips":["Never build trace-search UIs with an empty service selector unless the backend is known to support it.","Fetch /api/services first and require a selection before issuing searches.","Handle this as a 400 (it passes querysvc.IsBadRequest) so clients get InvalidArgument, not a 500."],"tags":["http-api","search","storage-backend","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"}