{"record":{"id":"62f7e1a8ae7df910","repo":"thanos-io/thanos","slug":"alertmanagers-url-contains-empty-scheme","errorCode":null,"errorMessage":"alertmanagers.url contains empty scheme","messagePattern":"alertmanagers\\.url contains empty scheme","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/alert/config.go","lineNumber":99,"sourceCode":"// LoadAlertingConfig loads a list of AlertmanagerConfig from YAML data.\nfunc LoadAlertingConfig(confYaml []byte) (AlertingConfig, error) {\n\tvar cfg AlertingConfig\n\tif err := yaml.UnmarshalStrict(confYaml, &cfg); err != nil {\n\t\treturn cfg, err\n\t}\n\treturn cfg, nil\n}\n\n// BuildAlertmanagerConfig initializes and returns an Alertmanager client configuration from a static address.\nfunc BuildAlertmanagerConfig(address string, timeout time.Duration) (AlertmanagerConfig, error) {\n\tparsed, err := url.Parse(address)\n\tif err != nil {\n\t\treturn AlertmanagerConfig{}, err\n\t}\n\n\tscheme := parsed.Scheme\n\tif scheme == \"\" {\n\t\treturn AlertmanagerConfig{}, errors.New(\"alertmanagers.url contains empty scheme\")\n\t}\n\n\thost := parsed.Host\n\tif host == \"\" {\n\t\treturn AlertmanagerConfig{}, errors.New(\"alertmanagers.url contains empty host\")\n\t}\n\n\tfor _, qType := range []dns.QType{dns.A, dns.SRV, dns.SRVNoA} {\n\t\tprefix := string(qType) + \"+\"\n\t\tif strings.HasPrefix(strings.ToLower(scheme), prefix) {\n\t\t\t// Scheme is of the form \"<dns type>+<http scheme>\".\n\t\t\tscheme = strings.TrimPrefix(scheme, prefix)\n\t\t\thost = prefix + parsed.Host\n\t\t\tif qType == dns.A {\n\t\t\t\tif _, _, err := net.SplitHostPort(parsed.Host); err != nil {\n\t\t\t\t\t// The host port could be missing. Append the defaultAlertmanagerPort.\n\t\t\t\t\thost = host + \":\" + strconv.Itoa(defaultAlertmanagerPort)\n\t\t\t\t}","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/alert/config.go#L81-L117","documentation":"BuildAlertmanagerConfig parses the alertmanagers.url and requires a URL scheme (http/https, or a dns-prefixed scheme like dns+http). An empty scheme means the URL was relative or malformed, so no HTTP client can be constructed.","triggerScenarios":"alertmanagers.sd_configs/static_configs url like \"alertmanager:9093\" or \":9093\" passed to BuildAlertmanagerConfig (called from runRule); url.Parse succeeds but parsed.Scheme is empty.","commonSituations":"Omitting http:// when writing the Alertmanager URL in rule/ruler config; config templating that renders an empty scheme prefix; port-only addresses copied from docker-compose.","solutions":["Prefix the URL with its scheme: use http://alertmanager:9093 (or https://...).","If the scheme must include DNS discovery, use the dns+http:// prefix form.","Add config validation/linting before startup to catch scheme-less URLs."],"exampleFix":"// before\nurl: alertmanager.monitoring:9093\n// after\nurl: http://alertmanager.monitoring:9093","handlingStrategy":"validation","validationCode":"u, err := url.Parse(cfg.URL)\nif err != nil || u.Scheme == \"\" {\n    return fmt.Errorf(\"alertmanagers.url %q must include a scheme, e.g. http://host:9093\", cfg.URL)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write Alertmanager URLs with explicit http:// or https://","Validate all URLs with net/url.Parse at config load time","Template-render configs and re-validate after substitution"],"tags":["config","url","alertmanager"],"backgroundTag":"invalid-url-format","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"}