fatedier/frp · error
no route found for destination %s
Error message
no route found for destination %s
What it means
vnet client-side routing error: the router (clientRouter.findConn) has no registered route whose CIDR contains the destination IP of the packet being tunneled. The vnet TUN device captured a packet whose destination lies outside every route configured/registered on this side; the message names the unmatched destination IP.
Source
Thrown at pkg/vnet/controller.go:304
r.mu.Lock()
defer r.mu.Unlock()
r.routes[name] = &routeElement{
routes: routes,
conn: conn,
}
}
func (r *clientRouter) findConn(dst net.IP) (io.Writer, error) {
r.mu.RLock()
defer r.mu.RUnlock()
for _, re := range r.routes {
for _, route := range re.routes {
if route.Contains(dst) {
return re.conn, nil
}
}
}
return nil, fmt.Errorf("no route found for destination %s", dst)
}
func (r *clientRouter) delRoute(name string) {
r.mu.Lock()
defer r.mu.Unlock()
delete(r.routes, name)
}
func (r *clientRouter) removeConnRoute(conn io.Writer) {
r.mu.Lock()
defer r.mu.Unlock()
for name, re := range r.routes {
if re.conn == conn {
delete(r.routes, name)
return
}
}
}View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Add a CIDR covering the destination to the routes of the side that originates the traffic: routes = ["10.0.0.0/24", "192.168.5.0/24"]
- Make sure routes are configured consistently on both frpc and frps vnet sections so registration completes
- Add more-specific OS routes (or adjust routes) so non-tunnel traffic (internet) is not captured by the TUN device
- Check the destination IP in the message against your route table with `ip route get <dst>`
Example fix
# before [vnet] routes = ["10.0.0.0/24"] # app calls 192.168.5.20 -> no route found for destination 192.168.5.20 # after [vnet] routes = ["10.0.0.0/24", "192.168.5.0/24"]
Defensive patterns
Strategy: validation
Validate before calling
// before sending, confirm dst is inside a configured vnet route
func covered(dst net.IP, routes []*net.IPNet) bool {
for _, r := range routes { if r.Contains(dst) { return true } }
return false
} Prevention
- Enumerate every subnet your apps will reach and mirror it in vnet routes on both ends
- After changing routes, restart frpc so registration messages refresh
- Check `ip route get <dst>` on the client to see whether traffic enters utun as intended
When it happens
Trigger: frpc with vnet enabled: an application sends traffic to an IP that is not inside any CIDR listed in the vnet routes (or the peer has not registered routes yet). Also a timing window right after startup before route registration messages arrive from the other side.
Common situations: routes on frpc cover 10.0.0.0/24 but the app targets 192.168.x.x;忘记 to mirror routes on both ends; accessing the TUN interface IP itself; sending to a public IP that should stay outside the tunnel but the OS routed it into utun.
Related errors
- no route found for source %s
- parse route %s error: %v
- subdomain is not supported because this feature is not enabl
- '.' and '*' are not supported in subdomain
- create encryption stream error: %v
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/e1807ae23c35948e.
Report an issue: GitHub.