{"record":{"id":"5d071440f8c8323c","repo":"thanos-io/thanos","slug":"error-parsing-query-string-when-enforcing-tenenac","errorCode":null,"errorMessage":"error parsing query string, when enforcing tenenacy","messagePattern":"error parsing query string, when enforcing tenenacy","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/tenancy/tenancy.go","lineNumber":154,"sourceCode":"\tmd, ok := metadata.FromIncomingContext(ctx)\n\tif !ok || len(md.Get(DefaultTenantHeader)) == 0 {\n\t\treturn DefaultTenant, false\n\t}\n\treturn md.Get(DefaultTenantHeader)[0], true\n}\n\nfunc EnforceQueryTenancy(tenantLabel string, tenant string, query string) (string, error) {\n\tlabelMatcher := &labels.Matcher{\n\t\tName:  tenantLabel,\n\t\tType:  labels.MatchEqual,\n\t\tValue: tenant,\n\t}\n\n\te := injectproxy.NewPromQLEnforcer(false, labelMatcher)\n\n\texpr, err := extpromql.ParseExpr(query)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"error parsing query string, when enforcing tenenacy\")\n\t}\n\n\tif err := e.EnforceNode(expr); err != nil {\n\t\treturn \"\", errors.Wrap(err, \"error enforcing label\")\n\t}\n\n\treturn expr.String(), nil\n}\n\nfunc getLabelMatchers(formMatchers []string, tenant string, enforceTenancy bool, tenantLabel string) ([][]*labels.Matcher, error) {\n\ttenantLabelMatcher := &labels.Matcher{\n\t\tName:  tenantLabel,\n\t\tType:  labels.MatchEqual,\n\t\tValue: tenant,\n\t}\n\n\tmatcherSets := make([][]*labels.Matcher, 0, len(formMatchers))\n","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/tenancy/tenancy.go#L136-L172","documentation":"EnforceQueryTenancy wraps a PromQL parse failure with this message. When tenancy is enforced, incoming PromQL queries are parsed with extpromql.ParseExpr before injecting tenant label matchers; if the query string is not syntactically valid PromQL, the wrapped error is returned and the query is rejected.","triggerScenarios":"EnforceQueryTenancy (called via RewritePromQL or HTTP handlers) receives a malformed query string, e.g. truncated expressions, invalid syntax, or non-PromQL payloads sent to query endpoints.","commonSituations":"Dashboard/tooling emitting malformed queries; clients URL-encoding incorrectly so operators get mangled; queries cut off by proxies or length limits; users typing invalid PromQL in Grafana pointed through the tenant proxy.","solutions":["Log/inspect the underlying wrapped error, which names the exact parse offset and token","Test the query in a standalone Prometheus/PromQL editor to confirm validity","Fix the client that produces the malformed query (escaping, truncation, encoding)","Check for proxy layers that mangle the query parameter (double-encoding, truncation)"],"exampleFix":"// before (malformed)\nup{job=\"foo\"\n// after\nup{job=\"foo\"}","handlingStrategy":"try-catch","validationCode":"// Pre-validate query client-side (JS)\nif (!query || query.trim().length === 0) throw new Error(\"empty PromQL query\");","typeGuard":null,"tryCatchPattern":"// Go\nrewritten, err := EnforceQueryTenancy(query, tenant, enforce)\nif err != nil && strings.Contains(err.Error(), \"error parsing query string\") {\n    http.Error(w, fmt.Sprintf(\"invalid PromQL: %v\", errors.Unwrap(err)), http.StatusBadRequest)\n    return\n}","preventionTips":["URL-encode query parameters correctly in clients","Validate queries against a local promql parser before sending","Watch for proxies that truncate or re-encode long query strings"],"tags":["promql","tenancy","query-parsing"],"backgroundTag":"invalid-argument-format","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}