fatedier/frp · error
parse route %s error: %v
Error message
parse route %s error: %v
What it means
Thrown by vnet's ParseRoutes when converting the routes config ([]string of CIDRs) to net.IPNet: net.ParseCIDR failed for one entry. Each route string must be a valid CIDR network including the prefix length; the message names the offending entry and the parse error. This runs during vnet (virtual network) controller setup on both frpc and frps.
Source
Thrown at pkg/vnet/controller.go:266
// UnregisterClientRoute Remove client route from routing table
func (c *Controller) UnregisterClientRoute(name string) {
c.clientRouter.delRoute(name)
}
// StartServerConnReadLoop starts the read loop for a server connection
// (dynamically associates with source IPs)
func (c *Controller) StartServerConnReadLoop(ctx context.Context, conn io.ReadWriteCloser, onClose func()) {
go c.readLoopServer(ctx, conn, onClose)
}
// ParseRoutes Convert route strings to IPNet objects
func ParseRoutes(routeStrings []string) ([]net.IPNet, error) {
routes := make([]net.IPNet, 0, len(routeStrings))
for _, r := range routeStrings {
_, ipNet, err := net.ParseCIDR(r)
if err != nil {
return nil, fmt.Errorf("parse route %s error: %v", r, err)
}
routes = append(routes, *ipNet)
}
return routes, nil
}
// Client router (based on destination IP routing)
type clientRouter struct {
routes map[string]*routeElement
mu sync.RWMutex
}
func newClientRouter() *clientRouter {
return &clientRouter{
routes: make(map[string]*routeElement),
}
}
View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Write every entry as base/prefix CIDR: routes = ["10.0.0.0/24", "fd00::/64"]
- Remove empty entries (no trailing commas) and any hostnames — only literal CIDRs are accepted
- Verify config (frpc verify / frps verify) before starting with vnet enabled
Example fix
# before [vnet] enabled = true routes = ["10.0.0.0"] # after [vnet] enabled = true routes = ["10.0.0.0/24"]
Defensive patterns
Strategy: validation
Validate before calling
func validCIDRs(routes []string) bool {
for _, r := range routes {
if _, _, err := net.ParseCIDR(strings.TrimSpace(r)); err != nil { return false }
}
return true
} Prevention
- Every vnet routes entry must be base/prefix CIDR, e.g. 10.0.0.0/24
- No hostnames, no bare IPs, no empty strings
- Run frpc/frps verify before enabling vnet in production
When it happens
Trigger: vnet.enabled = true with routes like "10.0.0.0" (missing /24), "10.0.0.1/8" (host bits — ParseCIDR still accepts this, but truly malformed like "10.0/8" or "abc" fails), empty strings, or IPv6 typos. The routes array in [vnet] section of frpc.toml/frps.toml.
Common situations: Writing bare IPs instead of CIDRs in routes; trailing comma producing an empty entry; assuming a DNS name or port range is allowed in routes.
Related errors
- no route found for destination %s
- no route found for source %s
- auth.oidc.clientID is required; auth.oidc.tokenEndpointURL i
- localAddr is required
- localPath is required
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/6f9e597c1a67b06f.
Report an issue: GitHub.