{"record":{"id":"c52a1dee0f4c6931","repo":"caddyserver/caddy","slug":"the-scheme-ws-is-only-supported-in-browsers-us","errorCode":null,"errorMessage":"the scheme ws:// is only supported in browsers; use http:// instead","messagePattern":"the scheme ws:// is only supported in browsers; use http:// instead","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"caddyconfig/httpcaddyfile/addresses.go","lineNumber":277,"sourceCode":"\t\t\t\taddressesWithProtocols: addressesWithProtocols,\n\t\t\t\tserverBlocks:           serverBlocks,\n\t\t\t})\n\t\t}\n\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","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/caddyconfig/httpcaddyfile/addresses.go#L259-L295","documentation":"A site address key used the ws:// scheme. Like wss://, it is a browser-side concept (WebSocket-over-HTTP); the server site should be http:// and Caddy serves WebSocket upgrades over plain HTTP automatically.","triggerScenarios":"A Caddyfile site block key starts with ws://, e.g. 'ws://example.com:8080 { }'.","commonSituations":"Using client WebSocket URLs (new WebSocket('ws://...')) as site addresses, often when reverse-proxying a WebSocket backend.","solutions":["Change ws:// to http:// in the site label","Configure the reverse_proxy to the backend as usual; no special WebSocket directive is needed"],"exampleFix":"# before\nws://example.com:8080 {\n}\n# after\nhttp://example.com:8080 {\n}","handlingStrategy":"validation","validationCode":"if strings.HasPrefix(siteKey, \"ws://\") {\n    return errors.New(\"use http:// for site addresses; clients keep ws://\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use http:// site labels for plain-HTTP WebSocket frontends","Remember Caddy proxies WebSockets without extra directives"],"tags":["caddyfile","websocket","site-address","scheme"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}