slackhq/nebula · error

entry %v.route in tun.unsafe_routes is contained within the

Error message

entry %v.route in tun.unsafe_routes is contained within the configured vpn networks; route: %v, network: %v

What it means

Config safety check in parseUnsafeRoutes: the i+1-th unsafe route's CIDR lies inside one of the configured VPN networks (network.Contains(route.Addr())). Routing the overlay's own address space back through a gateway would create a loop, so the whole config is rejected with both the route and the containing network named.

Source

Thrown at overlay/route.go:297

				return nil, fmt.Errorf("entry %v.install in tun.unsafe_routes is not a boolean: %v", i+1, err)
			}
		}

		r := Route{
			Via:     gateways,
			MTU:     mtu,
			Metric:  metric,
			Install: install,
		}

		r.Cidr, err = netip.ParsePrefix(fmt.Sprintf("%v", rRoute))
		if err != nil {
			return nil, fmt.Errorf("entry %v.route in tun.unsafe_routes failed to parse: %v", i+1, err)
		}

		for _, network := range networks {
			if network.Contains(r.Cidr.Addr()) {
				return nil, fmt.Errorf(
					"entry %v.route in tun.unsafe_routes is contained within the configured vpn networks; route: %v, network: %v",
					i+1,
					r.Cidr.String(),
					network.String(),
				)
			}
		}

		routes[i] = r
	}

	return routes, nil
}

func ipWithin(o *net.IPNet, i *net.IPNet) bool {
	// Make sure o contains the lowest form of i
	if !o.Contains(i.IP.Mask(i.Mask)) {
		return false

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Exclude the VPN's own subnets from tun.unsafe_routes
  2. Narrow the route to traffic outside the overlay networks
  3. Adjust the unsafe route CIDR so it does not fall inside any configured network
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at overlay/route.go:297 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/bf6e7cea81e97d4e. Report an issue: GitHub.