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

  1. Quote each label value: --selector-label='cluster="eu1"' (single outer quotes, double inner quotes).
  2. Check the resolved value inside your deployment manifest (Helm/Kustomize may strip or double-quote).
  3. Validate the label set with promtool or by running the flag through promutil.Labels locally.
  4. 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

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


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)