thanos-io/thanos · error

parsing config YAML file

Error message

parsing config YAML file

What it means

ParseRootLimitConfig reads a root limit-config YAML file and unmarshals it with yaml.UnmarshalStrict. This error wraps any YAML parsing or schema-mismatch failure, so the original yaml error (with line/column info) is preserved underneath. UnmarshalStrict means unknown fields in the file also trigger it.

Solutions

  1. Check the wrapped yaml error in the error chain for the exact line/column and fix the YAML syntax
  2. Remove or correct unknown fields — UnmarshalStrict rejects fields not present in RootLimitsConfig
  3. Validate types: e.g. max_connection or limit fields must be integers, not strings
  4. Run the file through a YAML linter and confirm top-level structure is writeLimits (with globalLimits etc.)
  5. Verify the file mounted/passed to the component is the intended config (not a secret manifest or empty file)

Example fix

// before (invalid: unknown key + bad type)
writeLimits:
  globalLimit:
    max_head_series: "100000"
// after
writeLimits:
  globalLimits:
    maxHeadSeries: 100000
Defensive patterns

Strategy: validation

Validate before calling

// Go: pre-validate YAML before calling ParseRootLimitConfig
if len(content) == 0 { return errors.New("limits config is empty") }
var probe map[string]interface{}
if err := yaml.Unmarshal(content, &probe); err != nil {
    return fmt.Errorf("invalid YAML: %w", err)
}
_, ok := probe["writeLimits"]
if !ok { return errors.New("missing writeLimits section") }

Type guard

func hasKnownKeys(root map[string]interface{}) bool {
    for k := range root {
        if k != "writeLimits" { return false }
    }
    return true
}

Try / catch

cfg, err := ParseRootLimitConfig(content)
if err != nil {
    var yErr yaml.TypeError
    if errors.As(err, &yErr) { log.Fatalf("config schema error: %v", err) }
    return fmt.Errorf("loading limits config: %w", err)
}

Prevention

When it happens

Trigger: Calling ParseRootLimitConfig (or ParseLimitConfigContent, or runReceive when loading --receive.limits-config) with malformed YAML, wrong indentation/types, or unknown top-level fields since strict unmarshaling is used.

Common situations: Hand-edited limits config files with bad indentation; typos in field names like 'writelimts'; passing JSON where YAML is expected with tabs; kubernetes secret mounted config containing stray whitespace or an old schema no longer recognized after a Thanos upgrade.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/8c9a55dd151a8ff3. Report an issue: GitHub.

Appendix: source

Thrown at pkg/receive/limiter_config.go:26

	"gopkg.in/yaml.v2"

	"github.com/thanos-io/thanos/pkg/clientconfig"
	"github.com/thanos-io/thanos/pkg/errors"
)

// RootLimitsConfig is the root configuration for limits.
type RootLimitsConfig struct {
	// WriteLimits hold the limits for writing data.
	WriteLimits WriteLimitsConfig `yaml:"write"`
}

// ParseRootLimitConfig parses the root limit configuration. Even though
// the result is a pointer, it will only be nil if an error is returned.
func ParseRootLimitConfig(content []byte) (*RootLimitsConfig, error) {
	var root RootLimitsConfig
	if err := yaml.UnmarshalStrict(content, &root); err != nil {
		return nil, errors.Wrapf(err, "parsing config YAML file")
	}

	if root.WriteLimits.GlobalLimits.MetaMonitoringURL != "" {
		u, err := url.Parse(root.WriteLimits.GlobalLimits.MetaMonitoringURL)
		if err != nil {
			return nil, errors.Wrapf(err, "parsing meta-monitoring URL")
		}

		// url.Parse might pass a URL with only path, so need to check here for scheme and host.
		// As per docs: https://pkg.go.dev/net/url#Parse.
		if u.Host == "" || u.Scheme == "" {
			return nil, errors.Newf("%s is not a valid meta-monitoring URL (scheme: %s,host: %s)", u, u.Scheme, u.Host)
		}
		root.WriteLimits.GlobalLimits.metaMonitoringURL = u
	}

	// Set default query if none specified.
	if root.WriteLimits.GlobalLimits.MetaMonitoringLimitQuery == "" {

View on GitHub (pinned to 35b8b99117)