{"record":{"id":"4314be2c1d59cf7f","repo":"fatedier/frp","slug":"v-s-s-s","errorCode":null,"errorMessage":"%v: %s %s %s","messagePattern":"%v: %s %s %s","errorType":"http","errorClass":"ErrNoRouteFound","httpStatus":null,"severity":"error","filePath":"pkg/util/vhost/http.go","lineNumber":184,"sourceCode":"}\n\n// CreateConnection create a new connection by route config\nfunc (rp *HTTPReverseProxy) CreateConnection(reqRouteInfo *RequestRouteInfo, byEndpoint bool) (net.Conn, error) {\n\thost, _ := httppkg.CanonicalHost(reqRouteInfo.Host)\n\tvr, ok := rp.vhostRouter.getByRoute(host, reqRouteInfo.URL, reqRouteInfo.HTTPUser)\n\tif ok {\n\t\tif byEndpoint {\n\t\t\tfn := vr.payload.(*RouteConfig).CreateConnByEndpointFn\n\t\t\tif fn != nil {\n\t\t\t\treturn fn(reqRouteInfo.Endpoint, reqRouteInfo.RemoteAddr)\n\t\t\t}\n\t\t}\n\t\tfn := vr.payload.(*RouteConfig).CreateConnFn\n\t\tif fn != nil {\n\t\t\treturn fn(reqRouteInfo.RemoteAddr)\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"%v: %s %s %s\", ErrNoRouteFound, host, reqRouteInfo.URL, reqRouteInfo.HTTPUser)\n}\n\nfunc checkRouteAuthByRequest(req *http.Request, rc *RouteConfig) bool {\n\tif rc == nil {\n\t\treturn true\n\t}\n\tif rc.Username == \"\" && rc.Password == \"\" {\n\t\treturn true\n\t}\n\n\tif req.URL.Host != \"\" {\n\t\tproxyAuth := req.Header.Get(\"Proxy-Authorization\")\n\t\tif proxyAuth == \"\" {\n\t\t\treturn false\n\t\t}\n\t\tuser, passwd, ok := httppkg.ParseBasicAuth(proxyAuth)\n\t\treturn ok && user == rc.Username && passwd == rc.Password\n\t}","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/util/vhost/http.go#L166-L202","documentation":"Vhost route-miss error from frp's HTTP vhost router: an incoming HTTP request's host, URL location, and HTTP user tuple matched no registered route. The message interpolates ErrNoRouteFound plus host, URL path and HTTPUser so you can see exactly what failed to match. In frps this typically becomes a 404 returned to the visitor.","triggerScenarios":"Request reaches frps's vhostHTTPPort with a Host header (domain/subdomain) that no frpc http/https proxy registered; correct domain but a URL path outside the proxy's configured locations; subdomain set but subdomainHost mismatch on the server; routeByHTTPUser configured and request lacking matching basic-auth user.","commonSituations":"DNS points to frps but the frpc proxy lacks customDomains/subdomains covering the requested host; subdomainHost not set (or set differently) in frps.toml so generated subdomains never match; wildcard expectations ('*.example.com') vs exact matching; proxy registered with locations = [\"/foo\"] while request hits /bar.","solutions":["Add the requested host to the frpc proxy: customDomains = [\"app.example.com\"] or subdomain = \"app\" (with subdomainHost = \"example.com\" in frps.toml)","If locations are configured, ensure the request path falls under one, or remove locations to match all paths","Confirm the Host header the client sends equals a registered domain (no port suffix issues; CanonicalHost is applied)","Check routeByHTTPUser: the basic-auth user in the request must match the routed user"],"exampleFix":"# before (frps.toml has subdomainHost, frpc proxy has neither)\n[[proxies]]\nname = \"web\"\ntype = \"http\"\nlocalPort = 8080\n\n# after\n[[proxies]]\nname = \"web\"\ntype = \"http\"\nlocalPort = 8080\nsubdomain = \"app\"\n# request Host: app.example.com now matches","handlingStrategy":"validation","validationCode":"// before pointing a domain at frps, confirm it will match a registered route\nexpected := \"app.example.com\"\n_ = expected // ensure frpc proxy has customDomains=[expected] or subdomain=\"app\" + subdomainHost=\"example.com\"","typeGuard":null,"tryCatchPattern":"body, err := io.ReadAll(resp.Body)\nif err == nil && resp.StatusCode == 404 && strings.Contains(string(body), \"no route found\") {\n    // host/location did not match any frpc proxy route: fix proxy config, not the client\n}","preventionTips":["Set subdomainHost in frps.toml and use subdomain on proxies for predictable matching","Keep an inventory mapping domain -> proxy name; verify after each change with curl -H 'Host: ...'","Remember locations match by path prefix — a wrong path looks identical to a wrong domain"],"tags":["vhost","http","routing","config"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}