slackhq/nebula · error
failed to set mtu %v on the default route %v; %v
Error message
failed to set mtu %v on the default route %v; %v
What it means
Raised by tun.setDefaultRoute (called from reload and Activate) when applying the configured DefaultMTU to the detected default route fails. The message includes the MTU, the default route (dr), and the underlying error, so you can see exactly which route couldn't be modified.
Source
Thrown at overlay/tun_linux.go:565
err := netlink.RouteReplace(&nr)
if err != nil {
t.l.Warn("Failed to set default route MTU, retrying", "error", err, "cidr", cidr)
//retry twice more -- on some systems there appears to be a race condition where if we set routes too soon, netlink says `invalid argument`
for i := 0; i < 2; i++ {
time.Sleep(100 * time.Millisecond)
err = netlink.RouteReplace(&nr)
if err == nil {
break
} else {
t.l.Warn("Failed to set default route MTU, retrying",
"error", err,
"cidr", cidr,
"mtu", t.DefaultMTU,
)
}
}
if err != nil {
return fmt.Errorf("failed to set mtu %v on the default route %v; %v", t.DefaultMTU, dr, err)
}
}
return nil
}
func (t *tun) addRoutes(logErrors bool) error {
// Path routes
routes := *t.Routes.Load()
for _, r := range routes {
if !r.Install {
continue
}
dr := &net.IPNet{
IP: r.Cidr.Masked().Addr().AsSlice(),
Mask: net.CIDRMask(r.Cidr.Bits(), r.Cidr.Addr().BitLen()),
}View on GitHub (pinned to dd8f660c0a)
Solutions
- Read dr and err in the message: if the route is 'none'/missing, ensure the host has a default route for that family.
- Run with CAP_NET_ADMIN to allow route attribute changes.
- Check that DefaultMTU in config is a valid MTU (e.g. 1300-1400 for overhead-heavy tunnels).
- If the default route flaps (DHCP), retry reload after the network stabilizes.
- Disable/adjust default-route MTU handling via config if your overlay doesn't need it.
Example fix
// before
# ip route (no default route for the family)
// after — provide a default route or set an explicit MTU
# ip route add default via 10.0.0.1
tun: { default_mtu: 1300 } Defensive patterns
Strategy: retry
Validate before calling
func defaultRouteExists(fam int) bool {
routes, err := netlink.RouteList(nil, fam)
if err != nil { return false }
for _, r := range routes {
if r.Dst == nil { return true } // default route
}
return false
} Try / catch
if err := activateOverlay(); err != nil {
if strings.Contains(err.Error(), "failed to set mtu") && strings.Contains(err.Error(), "default route") {
time.Sleep(time.Second)
err = activateOverlay() // default route may have just flapped
}
} Prevention
- Ensure a default route exists for both IPv4/IPv6 as needed
- Set a valid tun.default_mtu in config
- Run with CAP_NET_ADMIN
- Retry on DHCP-driven default-route flaps
When it happens
Trigger: reload() or Activate() runs while the host's default route cannot have its MTU updated via netlink — route not found (wrong address family), permission denied, or the route changed concurrently.
Common situations: No IPv4/IPv6 default route on the host while the CIDR requires one; lack of CAP_NET_ADMIN; flapping default route (DHCP renewals, VPN-over-VPN) changing the route between lookup and update.
Related errors
- failed to set default route MTU: %w
- unable to create AF_ROUTE socket: %v
- failed to create route.RouteMessage: %w
- failed to write route.RouteMessage to socket: %w
- unable to create AF_ROUTE socket: %v
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/83b97c44302705c6.
Report an issue: GitHub.