thanos-io/thanos · error
parse Prometheus config
Error message
parse Prometheus config: %v
What it means
After decoding the config JSON, ExternalLabels parses the embedded Prometheus configuration YAML to extract global.external_labels. This error wraps yaml.Unmarshal failures, embedding the raw YAML text so the malformed config can be inspected.
Solutions
- Inspect the YAML included in the error message for syntax problems
- Validate the Prometheus config with promtool check config
- Ensure external_labels values are plain strings in prometheus.yml
- Simplify generated config (avoid exotic YAML anchors) and reload Prometheus
Example fix
// before (prometheus.yml)
global:
external_labels:
cluster: &anchor {name: prod} # map where string expected
// after
global:
external_labels:
cluster: prod
name: prod Defensive patterns
Strategy: validation
Validate before calling
func externalLabelsAreStrings(cfgYAML string) error {
var probe struct {
Global struct {
ExternalLabels map[string]string `yaml:"external_labels"`
} `yaml:"global"`
}
return yaml.Unmarshal([]byte(cfgYAML), &probe)
} Try / catch
labels, err := client.ExternalLabels(ctx, baseURL)
if err != nil {
if strings.Contains(err.Error(), "parse Prometheus config") {
log.Printf("prometheus config YAML invalid: %v", err)
}
return err
} Prevention
- Run promtool check config on prometheus.yml after every change
- Keep external_labels values as plain quoted strings
- Avoid exotic YAML features (anchors with complex types) in generated configs
When it happens
Trigger: The YAML string inside data.yaml of the /api/v1/status/config response cannot be unmarshaled into the expected {global: {external_labels: map[string]string}} structure — e.g. YAML with anchors/templating the parser rejects, or non-string external label values.
Common situations: Prometheus config generated with unsupported YAML features (anchors producing exotic types); external_labels values that are not strings; corrupted config served by a proxy cache; third-party Prometheus forks emitting a different config format.
Related errors
- unable to unmarshal config content
- parsing downstream tripper config YAML file
- parsing downstream tripper TLS config YAML
- initializing the query range cache config
- initializing the labels cache config
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/a9f8ad5599a48fe7.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/promclient/promclient.go:209
body, _, err := c.req2xx(ctx, &u, http.MethodGet, nil)
if err != nil {
return labels.EmptyLabels(), err
}
var d struct {
Data struct {
YAML string `json:"yaml"`
} `json:"data"`
}
if err := json.Unmarshal(body, &d); err != nil {
return labels.EmptyLabels(), errors.Wrapf(err, "unmarshal response: %v", string(body))
}
var cfg struct {
GlobalConfig struct {
ExternalLabels map[string]string `yaml:"external_labels"`
} `yaml:"global"`
}
if err := yaml.Unmarshal([]byte(d.Data.YAML), &cfg); err != nil {
return labels.EmptyLabels(), errors.Wrapf(err, "parse Prometheus config: %v", d.Data.YAML)
}
return labels.FromMap(cfg.GlobalConfig.ExternalLabels), nil
}
type Flags struct {
TSDBPath string `json:"storage.tsdb.path"`
TSDBRetention model.Duration `json:"storage.tsdb.retention"`
TSDBMinTime model.Duration `json:"storage.tsdb.min-block-duration"`
TSDBMaxTime model.Duration `json:"storage.tsdb.max-block-duration"`
TSDBDelayCompact string `json:"storage.tsdb.delay-compact-file.path"`
WebEnableAdminAPI bool `json:"web.enable-admin-api"`
WebEnableLifecycle bool `json:"web.enable-lifecycle"`
}
// UnmarshalJSON implements the json.Unmarshaler interface.
func (f *Flags) UnmarshalJSON(b []byte) error {
// TODO(bwplotka): Avoid this custom unmarshal by:View on GitHub (pinned to 35b8b99117)