{"record":{"id":"5c8d9d743129e23a","repo":"jaegertracing/jaeger","slug":"the-structured-query-filter-is-disabled","errorCode":null,"errorMessage":"the structured query filter is disabled","messagePattern":"the structured query filter is disabled","errorType":"exception","errorClass":null,"httpStatus":400,"severity":"error","filePath":"cmd/jaeger/internal/extension/jaegerquery/querysvc/filter.go","lineNumber":37,"sourceCode":"// separate switch, named jaeger.<backend>.structuredFilters — this gate's leaf with the backend\n// in place of \"query\" — because the two stabilize on different schedules.\nvar StructuredFiltersGate = featuregate.GlobalRegistry().MustRegister(\n\t\"jaeger.query.structuredFilters\",\n\tfeaturegate.StageAlpha,\n\tfeaturegate.WithRegisterFromVersion(\"v2.21.0\"),\n\tfeaturegate.WithRegisterDescription(\n\t\t\"Accepts the RFC 0005 structured query filter on trace search. The filter AST is not yet \"+\n\t\t\t\"stable, so a query that carries one is refused while this is disabled. This admits \"+\n\t\t\t\"filters into the query path only; whether a storage backend evaluates one natively is \"+\n\t\t\t\"gated separately, by jaeger.<backend>.structuredFilters.\",\n\t),\n\tfeaturegate.WithRegisterReferenceURL(\"https://github.com/jaegertracing/jaeger/blob/main/docs/rfc/0005-structured-query-filters.md\"),\n)\n\n// ErrFilterDisabled is returned for a query carrying a filter to a deployment that has not\n// enabled StructuredFiltersGate. The query is refused rather than served with the filter\n// ignored, because dropping a predicate would answer with every trace in the time range.\nvar ErrFilterDisabled = errors.New(\"the structured query filter is disabled\")\n\n// IsBadRequest reports whether err means the caller must change the query, either\n// because its shape is wrong or because this deployment's storage cannot serve it.\n// Either way it is the caller's problem, so the API layers answer InvalidArgument /\n// HTTP 400 rather than reporting a server fault.\nfunc IsBadRequest(err error) bool {\n\treturn errors.Is(err, ErrServiceNameRequired) ||\n\t\terrors.Is(err, ErrFilterDisabled) ||\n\t\terrors.Is(err, tracestore.ErrFilterUnsupported) ||\n\t\terrors.Is(err, tracestore.ErrFilterInvalid)\n}\n","sourceCodeStart":19,"sourceCodeEnd":49,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/cmd/jaeger/internal/extension/jaegerquery/querysvc/filter.go#L19-L49","documentation":"ErrFilterDisabled is returned when a trace search carries a structured query filter (RFC 0005) but the deployment has not enabled the StructuredFiltersGate feature gate. The service refuses the query instead of silently dropping the filter, because ignoring a predicate would return every trace in the time range — a dangerously different answer. It is classified as a bad request: the caller must change the query or the operator must enable the gate.","triggerScenarios":"Sending a search whose TraceQueryParams include structured filter predicates (e.g. tag/attribute filters via the JSON query filter syntax) to a jaegerquery instance started without the structured-filters feature gate enabled.","commonSituations":"A client library upgraded to use structured filters while the server runs an older/default configuration; an operator rolling out RFC 0005 support without flipping the feature gate; staging environments where the gate is on but production is not.","solutions":["Enable the structured-filters feature gate on the jaegerquery server (e.g. --query.feature-gates=structuredFilters or the equivalent config entry).","If the gate cannot be enabled, rewrite the search to use legacy tag matching or plain query parameters instead of the structured filter syntax.","Check querysvc.IsBadRequest handling in your API layer so this surfaces as HTTP 400 / gRPC InvalidArgument with a clear message rather than a 500."],"exampleFix":"// before: server started without the gate\njaeger-query --span-storage.type=elasticsearch\n// after: enable the gate for structured filter support\njaeger-query --span-storage.type=elasticsearch --query.feature-gates=structuredFilters","handlingStrategy":"type-guard","validationCode":"if !gateEnabled(\"structuredFilters\") && hasStructuredFilter(query) {\n    // strip the filter or rewrite to legacy tag matching before sending\n    query.Filter = nil\n}","typeGuard":"func isFilterDisabled(err error) bool { return errors.Is(err, querysvc.ErrFilterDisabled) }","tryCatchPattern":"if err := svc.FindTraces(ctx, q, onTrace); err != nil {\n    if errors.Is(err, querysvc.ErrFilterDisabled) {\n        // 400 for the user: retry without filter or tell them to enable the gate\n        return status.Error(codes.InvalidArgument, err.Error())\n    }\n    return err\n}","preventionTips":["Align feature-gate settings across environments so clients never rely on a gate that is off in prod.","Have clients detect the error and degrade gracefully to legacy tag search.","Document the gate requirement wherever structured filter queries are generated."],"tags":["feature-gate","query-filter","configuration"],"backgroundTag":"feature-flag-disabled","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}