slackhq/nebula · error

failed to set tun address: %s

Error message

failed to set tun address: %s

What it means

activate6() assigns an IPv6 address to the utun device using the SIOCAIFADDR_IN6 ioctl, with DAD disabled (_IN6_IFF_NODAD). This error wraps the errno when the kernel rejects the IPv6 address assignment for an IPv6 VPN network in the config.

Source

Thrown at overlay/tun_darwin.go:298

			Len:    unix.SizeofSockaddrInet6,
			Family: unix.AF_INET6,
			Addr:   network.Addr().As16(),
		},
		PrefixMask: unix.RawSockaddrInet6{
			Len:    unix.SizeofSockaddrInet6,
			Family: unix.AF_INET6,
			Addr:   prefixToMask(network).As16(),
		},
		Lifetime: addrLifetime{
			// never expires
			Vltime: 0xffffffff,
			Pltime: 0xffffffff,
		},
		Flags: _IN6_IFF_NODAD,
	}

	if err := ioctl(uintptr(s), _SIOCAIFADDR_IN6, uintptr(unsafe.Pointer(&ifr))); err != nil {
		return fmt.Errorf("failed to set tun address: %s", err)
	}

	return nil
}

func (t *tun) reload(c *config.C, initial bool) error {
	change, routes, err := getAllRoutesFromConfig(c, t.vpnNetworks, initial)
	if err != nil {
		return err
	}

	if !initial && !change {
		return nil
	}

	routeTree, err := makeRouteTree(t.l, routes, false)
	if err != nil {
		return err

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Confirm IPv6 is enabled on the host (`netstat -rn | head` shows inet6 routes or `sysctl net.inet6`); enable it or remove the IPv6 entry from the config.
  2. Check the wrapped errno (EEXIST => address already assigned) and choose a non-conflicting IPv6 prefix.
  3. Run nebula with sufficient privileges to change interface addresses.
  4. Verify the IPv6 prefix in the config is well-formed (e.g. fd00::/8 ULA style).

Example fix

// before: IPv6 disabled on host but configured
 cert_name...
tun:
  routes:
    - route: fd00::/8
// after: remove IPv6 route or enable IPv6 on the host
tun:
  routes: []
Defensive patterns

Strategy: validation

Validate before calling

out, err := exec.Command("sysctl", "net.inet6.ip6.forwarding").Output()
_ = out
if err != nil {
    return fmt.Errorf("IPv6 appears disabled on this host; remove IPv6 tun routes or enable IPv6")
}
prefix, err := netip.ParsePrefix(cfg.TunRoute6)
if err != nil || !prefix.Addr().Is6() {
    return fmt.Errorf("tun route must be a valid IPv6 prefix: %w", err)
}

Try / catch

if err := iface.Activate(); err != nil {
    if strings.Contains(err.Error(), "failed to set tun address") {
        // IPv6 rejected: enable host IPv6 or drop the IPv6 route from config
    }
    return err
}

Prevention

When it happens

Trigger: Activate() -> activate6() for each IPv6 vpnNetwork prefix; the SIOCAIFADDR_IN6 ioctl fails, e.g. IPv6 is disabled in the kernel, the address is already in use, or the requested utun device is invalid.

Common situations: Hosts with IPv6 disabled at the OS level while the nebula config still lists an IPv6 tun network; address collisions with an existing IPv6 interface; running without sufficient privileges.

Related errors


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