{"record":{"id":"d54890e1058b4e2c","repo":"thanos-io/thanos","slug":"parsing-meta-monitoring-url","errorCode":null,"errorMessage":"parsing meta-monitoring URL","messagePattern":"parsing meta-monitoring URL","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/receive/limiter_config.go","lineNumber":32,"sourceCode":"\n// RootLimitsConfig is the root configuration for limits.\ntype RootLimitsConfig struct {\n\t// WriteLimits hold the limits for writing data.\n\tWriteLimits WriteLimitsConfig `yaml:\"write\"`\n}\n\n// ParseRootLimitConfig parses the root limit configuration. Even though\n// the result is a pointer, it will only be nil if an error is returned.\nfunc ParseRootLimitConfig(content []byte) (*RootLimitsConfig, error) {\n\tvar root RootLimitsConfig\n\tif err := yaml.UnmarshalStrict(content, &root); err != nil {\n\t\treturn nil, errors.Wrapf(err, \"parsing config YAML file\")\n\t}\n\n\tif root.WriteLimits.GlobalLimits.MetaMonitoringURL != \"\" {\n\t\tu, err := url.Parse(root.WriteLimits.GlobalLimits.MetaMonitoringURL)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrapf(err, \"parsing meta-monitoring URL\")\n\t\t}\n\n\t\t// url.Parse might pass a URL with only path, so need to check here for scheme and host.\n\t\t// As per docs: https://pkg.go.dev/net/url#Parse.\n\t\tif u.Host == \"\" || u.Scheme == \"\" {\n\t\t\treturn nil, errors.Newf(\"%s is not a valid meta-monitoring URL (scheme: %s,host: %s)\", u, u.Scheme, u.Host)\n\t\t}\n\t\troot.WriteLimits.GlobalLimits.metaMonitoringURL = u\n\t}\n\n\t// Set default query if none specified.\n\tif root.WriteLimits.GlobalLimits.MetaMonitoringLimitQuery == \"\" {\n\t\troot.WriteLimits.GlobalLimits.MetaMonitoringLimitQuery = \"sum(prometheus_tsdb_head_series) by (tenant)\"\n\t}\n\n\treturn &root, nil\n}\n","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/receive/limiter_config.go#L14-L50","documentation":"After parsing the config, ParseRootLimitConfig validates the writeLimits.globalLimits.metaMonitoringURL field with url.Parse. url.Parse accepts bare paths, so this error plus the explicit scheme/host check guards against a URL that would not be usable as an HTTP endpoint.","triggerScenarios":"Setting metaMonitoringURL to a value without a scheme (e.g. 'localhost:8080' parses oddly, 'metrics.local/meta'), or a string that url.Parse rejects entirely (invalid characters, unmatched brackets, e.g. 'http://[::1').","commonSituations":"Operator forgets http:// or https:// prefix; copies a URL with quotes or spaces from docs; uses DNS-only name with a path; misconfigured Helm values producing 'null' or empty-ish URL strings.","solutions":["Read the wrapped url.Parse error for the specific syntax problem and fix the URL","Ensure the value includes both a scheme and host, e.g. http://metrics.local:9090","Check kubernetes/helm values so templating does not inject literal quotes or 'null'","If no meta-monitoring endpoint is desired, leave metaMonitoringURL empty instead of a placeholder"],"exampleFix":"# before\nwriteLimits:\n  globalLimits:\n    metaMonitoringURL: \"thanos-metrics.local/api/v1/write\"\n# after\nwriteLimits:\n  globalLimits:\n    metaMonitoringURL: \"http://thanos-metrics.local/api/v1/write\"","handlingStrategy":"validation","validationCode":"func validMetaMonitoringURL(u string) bool {\n    if u == \"\" { return true }\n    parsed, err := url.Parse(u)\n    return err == nil && parsed.Host != \"\" && parsed.Scheme != \"\"\n}\n// call before constructing RootLimitsConfig","typeGuard":"func isUsableURL(u *url.URL) bool { return u != nil && u.Scheme != \"\" && u.Host != \"\" }","tryCatchPattern":"cfg, err := ParseRootLimitConfig(content)\nif err != nil {\n    if strings.Contains(err.Error(), \"meta-monitoring URL\") {\n        log.Fatalf(\"fix metaMonitoringURL in config: %v\", err)\n    }\n    return err\n}","preventionTips":["Always include scheme (http:// or https://) in metaMonitoringURL values","Render templates and verify the final string has no quotes/null artifacts","Add a preflight config validation step in CI"],"tags":["url","config","validation"],"backgroundTag":"invalid-url","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}