{"record":{"id":"1f05c8b9df441f23","repo":"caddyserver/caddy","slug":"unsupported-url-scheme-s","errorCode":null,"errorMessage":"unsupported URL scheme %s://","messagePattern":"unsupported URL scheme (.+?)://","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"caddyconfig/httpcaddyfile/addresses.go","lineNumber":281,"sourceCode":"\t}\n\n\treturn sbaddrs\n}\n\n// listenersForServerBlockAddress essentially converts the Caddyfile site addresses to a map from\n// Caddy listener addresses and the protocols to serve them with to the parsed address for each server block.\nfunc (st *ServerType) listenersForServerBlockAddress(sblock serverBlock, addr Address,\n\toptions map[string]any,\n) (map[string]map[string]struct{}, error) {\n\tswitch addr.Scheme {\n\tcase \"wss\":\n\t\treturn nil, fmt.Errorf(\"the scheme wss:// is only supported in browsers; use https:// instead\")\n\tcase \"ws\":\n\t\treturn nil, fmt.Errorf(\"the scheme ws:// is only supported in browsers; use http:// instead\")\n\tcase \"https\", \"http\", \"\":\n\t\t// Do nothing or handle the valid schemes\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported URL scheme %s://\", addr.Scheme)\n\t}\n\n\t// figure out the HTTP and HTTPS ports; either\n\t// use defaults, or override with user config\n\thttpPort, httpsPort := strconv.Itoa(caddyhttp.DefaultHTTPPort), strconv.Itoa(caddyhttp.DefaultHTTPSPort)\n\tif hport, ok := options[\"http_port\"]; ok {\n\t\thttpPort = strconv.Itoa(hport.(int))\n\t}\n\tif hsport, ok := options[\"https_port\"]; ok {\n\t\thttpsPort = strconv.Itoa(hsport.(int))\n\t}\n\n\t// default port is the HTTPS port\n\tlnPort := httpsPort\n\tif addr.Port != \"\" {\n\t\t// port explicitly defined\n\t\tlnPort = addr.Port\n\t} else if addr.Scheme == \"http\" {","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/caddyconfig/httpcaddyfile/addresses.go#L263-L299","documentation":"The site address scheme is none of http, https, ws, wss, or empty — Caddy does not know how to serve it. The message echoes the scheme so the offending label is obvious.","triggerScenarios":"A site key with an arbitrary scheme such as ftp://example.com or tcp://example.com; only http/https (and their WebSocket browser aliases, which get their own errors) are valid for site addresses.","commonSituations":"Confusing Caddy site addresses with proxy upstream URLs (e.g. writing fastcgi:// or tcp:// as a site label), or typos like 'httpss://'.","solutions":["Remove or correct the scheme; site addresses accept no scheme, http://, or https://","If you meant a proxy target, put that URL in reverse_proxy, not in the site label","For non-HTTP listeners, use the global servers/layer4-style plugins rather than an HTTP site address"],"exampleFix":"# before\nftp://example.com {\n}\n# after\nexample.com {\n}","handlingStrategy":"type-guard","validationCode":"var schemeRe = regexp.MustCompile(`^(https?://)?`)\nif !schemeRe.MatchString(siteKey) || strings.Contains(siteKey, \"://\") && !strings.HasPrefix(siteKey, \"http://\") && !strings.HasPrefix(siteKey, \"https://\") {\n    return fmt.Errorf(\"site address %q must use http, https, or no scheme\", siteKey)\n}","typeGuard":"func isSupportedScheme(s string) bool {\n    switch s {\n    case \"\", \"http\", \"https\":\n        return true\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["Only http:// and https:// (or scheme-less) in site labels","Put backend protocol schemes in reverse_proxy upstreams"],"tags":["caddyfile","site-address","scheme"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}