thanos-io/thanos · error
parse federation labels
Error message
parse federation labels
What it means
The query command parses the --selector-label flag (repeated external/federation labels that identify this query frontend) via parseFlagLabels; if the value is not a valid PromQL label set, it returns the error wrapped as "parse federation labels" during setup.
Solutions
- Quote each label value: --selector-label='cluster="eu1"' (single outer quotes, double inner quotes).
- Check the resolved value inside your deployment manifest (Helm/Kustomize may strip or double-quote).
- Validate the label set with promtool or by running the flag through promutil.Labels locally.
- Use --log.level=debug to see the raw flag values Thanos received.
Example fix
// before args: ["query", "--selector-label=cluster=eu1"] // after args: ["query", "--selector-label=cluster=\"eu1\""]
Defensive patterns
Strategy: validation
Validate before calling
// Validate selector labels before launching
import "github.com/thanos-io/thanos/pkg/store/labelproxy"
if _, err := parseFlagLabels(flagValue); err != nil {
return fmt.Errorf("selector-label invalid: %w", err)
} Try / catch
sel, err := promutil.ParseLabels(flagVal)
if err != nil {
return fmt.Errorf("bad --selector-label %q: %w", flagVal, err)
} Prevention
- Always use single-quoted shell values with double-quoted label values: 'k="v"'
- In YAML args arrays, escape inner double quotes
- Render templates (helm template) and inspect the final argv before deploy
When it happens
Trigger: Calling `thanos query --selector-label=...` where the flag value cannot be parsed as a valid promutil.Labels() set — e.g. missing quotes, unbalanced braces, invalid label name characters, or empty values.
Common situations: Shell stripping quotes (e.g. --selector-label='replica="r1"' written without inner quotes in YAML), Kubernetes manifests where quoted values get mangled, or typos like '=' instead of '="..."'.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- unable to parse external labels
- unrecognized label
- unsupported format for label
- unquote label value
- parse labels
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/84c4e1f5ad72ff2c.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/thanos/query.go:222
endpointGroups := extkingpin.Addrs(cmd.Flag("endpoint-group", "(Deprecated, Experimental): DNS name of statically configured Thanos API server groups (repeatable). Targets resolved from the DNS name will be queried in a round-robin, instead of a fanout manner. This flag should be used when connecting a Thanos Query to HA groups of Thanos components.").PlaceHolder("<endpoint-group>"))
strictEndpoints := extkingpin.Addrs(cmd.Flag("endpoint-strict", "(Deprecated): Addresses of only statically configured Thanos API servers that are always used, even if the health check fails. Useful if you have a caching layer on top.").
PlaceHolder("<endpoint-strict>"))
strictEndpointGroups := extkingpin.Addrs(cmd.Flag("endpoint-group-strict", "(Deprecated, Experimental): DNS name of statically configured Thanos API server groups (repeatable) that are always used, even if the health check fails.").PlaceHolder("<endpoint-group-strict>"))
injectTestAddresses := extkingpin.Addrs(cmd.Flag("inject-test-addresses", "Inject test addresses for DNS resolver (repeatable).").PlaceHolder("<inject-test-address>").Hidden())
lazyRetrievalMaxBufferedResponses := cmd.Flag("query.lazy-retrieval-max-buffered-responses", "The lazy retrieval strategy can buffer up to this number of responses. This is to limit the memory usage. This flag takes effect only when the lazy retrieval strategy is enabled.").
Default("20").Hidden().Int()
var storeRateLimits store.SeriesSelectLimits
storeRateLimits.RegisterFlags(cmd)
cmd.Setup(func(g *run.Group, logger log.Logger, reg *prometheus.Registry, tracer opentracing.Tracer, _ <-chan struct{}, debugLogging bool) error {
selectorLset, err := parseFlagLabels(*selectorLabels)
if err != nil {
return errors.Wrap(err, "parse federation labels")
}
for _, feature := range *featureList {
if feature == promqlExperimentalFunctions {
parser.EnableExperimentalFunctions = true
level.Info(logger).Log("msg", "Experimental PromQL functions enabled.", "option", promqlExperimentalFunctions)
}
if feature == promqlAtModifier {
level.Warn(logger).Log("msg", "This option for --enable-feature is now permanently enabled and therefore a no-op.", "option", promqlAtModifier)
}
if feature == promqlNegativeOffset {
level.Warn(logger).Log("msg", "This option for --enable-feature is now permanently enabled and therefore a no-op.", "option", promqlNegativeOffset)
}
if feature == queryPushdown {
level.Warn(logger).Log("msg", "This option for --enable-feature is now permanently deprecated and therefore ignored.", "option", queryPushdown)
}
}
View on GitHub (pinned to 35b8b99117)