thanos-io/thanos · error
: failed to marshal rule groups
Error message
%s: failed to marshal rule groups
What it means
Raised in Manager.Update while re-serializing each parsed rule group file back to YAML, grouped by partial-response strategy, into the manager's workDir. It fires when yaml.Marshal of a strategy's configGroups fails, which is unexpected since the groups were just unmarshaled successfully; it indicates a serialization defect or unsupported field content, and that strategy's rule file is skipped.
Solutions
- Check the rule group content for fields that fail YAML marshaling
- Update Thanos/Prometheus rule config structs if a newly supported field is not marshalable
- Inspect the wrapped yaml.Marshal error to identify the offending field
Defensive patterns
Strategy: try-catch
When it happens
Trigger: Thrown at pkg/rules/manager.go:364 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/9bc4d6705335b269.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/rules/manager.go:364
continue
}
var rg configGroups
if err := yaml.Unmarshal(b, &rg); err != nil {
errs.Add(errors.Wrap(err, fn))
continue
}
// NOTE: This is very ugly, but we need to write those yaml into tmp dir without the partial partial response field
// which is not supported, to be able to reuse rules.Manager. The problem is that it uses yaml.UnmarshalStrict.
groupsByStrategy := map[storepb.PartialResponseStrategy][]configRuleAdapter{}
for _, rg := range rg.Groups {
groupsByStrategy[*rg.PartialResponseStrategy] = append(groupsByStrategy[*rg.PartialResponseStrategy], rg)
}
for s, rg := range groupsByStrategy {
b, err := yaml.Marshal(configGroups{Groups: rg})
if err != nil {
errs = append(errs, errors.Wrapf(err, "%s: failed to marshal rule groups", fn))
continue
}
// Use full file name appending to work dir, so we can differentiate between different dirs and same filenames(!).
// This will be also used as key for file group name.
newFn := filepath.Join(m.workDir, s.String(), fn)
if err := os.MkdirAll(filepath.Dir(newFn), os.ModePerm); err != nil {
errs.Add(errors.Wrapf(err, "create %s", filepath.Dir(newFn)))
continue
}
if err := os.WriteFile(newFn, b, os.ModePerm); err != nil {
errs.Add(errors.Wrapf(err, "write file %v", newFn))
continue
}
filesByStrategy[s] = append(filesByStrategy[s], newFn)
ruleFiles[newFn] = fn
}
}View on GitHub (pinned to 35b8b99117)