thanos-io/thanos · error
parse labels
Error message
parse labels
What it means
The rule component's Setup hook parses the repeated --label flag values via parseFlagLabels into Prometheus external labels. This wraps the error returned when a label string is not valid 'key="value"' YAML or the key is reserved/invalid. Startup aborts because external labels are required for rule-produced data.
Solutions
- Quote the value: --label 'cluster="prod"' (YAML string syntax), and escape for your shell.
- Remove or rename any reserved label keys (rule, alertsource, thanos_member, etc.).
- Test the label string as YAML, e.g. echo 'cluster: "prod"' | yamllint, to confirm it parses.
- Upgrade/downgrade Thanos if behavior of reserved labels changed between versions.
Example fix
// before thanos rule --label cluster=prod --label replica=1 // after thanos rule --label 'cluster="prod"' --label 'replica="1"'
Defensive patterns
Strategy: validation
Validate before calling
import yaml
def check_label_flag(value):
node = yaml.safe_load(value) # e.g. 'cluster="prod"'
if not isinstance(node, dict) or len(node) != 1:
raise SystemExit(f"--label must be key=\"value\" YAML: {value!r}")
reserved = {"rule", "alertsource", "thanos_member"}
key = next(iter(node))
if key in reserved:
raise SystemExit(f"label key {key} is reserved") Type guard
def is_valid_label(s):
import yaml
try:
d = yaml.safe_load(s)
return isinstance(d, dict) and len(d) == 1 and all(isinstance(v, str) for v in d.values())
except yaml.YAMLError:
return False Prevention
- Always quote label values: --label 'key="value"'.
- Keep a shellcheck-tested wrapper script for thanos flags.
- Avoid Thanos-reserved label names for external labels.
- Test flag parsing in CI by launching thanos rule with --help-arg validation or a dry setup.
When it happens
Trigger: A --label flag value like "cluster" (no value) or "cluster=prod" with unquoted special characters fails YAML unmarshaling into labels.Labels, or the key collides with Thanos-reserved labels such as rule or alertsource.
Common situations: User writes --label cluster=prod instead of the expected --label 'cluster="prod"' form; shell quoting strips the inner quotes; using a reserved label name.
Understand the failure class
Background: "unknown output mode", "invalid value for flag", "expects true/false": fixing invalid flag value errors in CLI tools — this error's family across 24 libraries.
Related errors
- unrecognized label
- unsupported format for label
- unquote label value
- parse alert query url
- no query configuration parameter was given
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/5e6dc5d407ce0c74.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/thanos/rule.go:191
cmd.Flag("query.enable-x-functions", "Whether to enable extended rate functions (xrate, xincrease and xdelta). Only has effect when used with Thanos engine.").Default("false").BoolVar(&conf.extendedFunctionsEnabled)
cmd.Flag("enable-feature", "Comma separated feature names to enable. Valid options for now: promql-experimental-functions (enables promql experimental functions for ruler)").Default("").StringsVar(&conf.EnableFeatures)
cmd.Flag("tsdb.enable-native-histograms",
"(Deprecated) Enables the ingestion of native histograms. This flag is a no-op now and will be removed in the future. Native histogram ingestion is always enabled.").
Default("true").BoolVar(&conf.tsdbEnableNativeHistograms)
conf.rwConfig = extflag.RegisterPathOrContent(cmd, "remote-write.config", "YAML config for the remote-write configurations, that specify servers where samples should be sent to (see https://prometheus.io/docs/prometheus/latest/configuration/configuration/#remote_write). This automatically enables stateless mode for ruler and no series will be stored in the ruler's TSDB. If an empty config (or file) is provided, the flag is ignored and ruler is run with its own TSDB.", extflag.WithEnvSubstitution())
conf.objStoreConfig = extkingpin.RegisterCommonObjStoreFlags(cmd, "", false)
reqLogConfig := extkingpin.RegisterRequestLoggingFlags(cmd)
var err error
cmd.Setup(func(g *run.Group, logger log.Logger, reg *prometheus.Registry, tracer opentracing.Tracer, reload <-chan struct{}, _ bool) error {
conf.lset, err = parseFlagLabels(*labelStrs)
if err != nil {
return errors.Wrap(err, "parse labels")
}
conf.alertQueryURL, err = url.Parse(*conf.alertmgr.alertQueryURL)
if err != nil {
return errors.Wrap(err, "parse alert query url")
}
tsdbOpts := &tsdb.Options{
MinBlockDuration: int64(time.Duration(*tsdbBlockDuration) / time.Millisecond),
MaxBlockDuration: int64(time.Duration(*tsdbBlockDuration) / time.Millisecond),
RetentionDuration: int64(time.Duration(*tsdbRetention) / time.Millisecond),
NoLockfile: *noLockFile,
WALCompression: compressutil.ParseCompressionType(*walCompression, compression.Snappy),
}
agentOpts := &agent.Options{
WALCompression: compressutil.ParseCompressionType(*walCompression, compression.Snappy),
NoLockfile: *noLockFile,View on GitHub (pinned to 35b8b99117)