slackhq/nebula · error

unable to discover link_addr for tun interface

Error message

unable to discover link_addr for tun interface

What it means

Activate calls getLinkAddr to find the link-layer (AF_LINK) address record for the utun interface, which nebula needs for route/address setup. If the lookup succeeds but returns no matching link address, this error is returned. It means the kernel knows the interface by name but no link_addr entry could be discovered for it.

Source

Thrown at overlay/tun_darwin.go:196

	// Set the MTU on the device
	ifm := ifreqMTU{Name: devName, MTU: int32(t.DefaultMTU)}
	if err = ioctl(fd, unix.SIOCSIFMTU, uintptr(unsafe.Pointer(&ifm))); err != nil {
		return fmt.Errorf("failed to set tun mtu: %v", err)
	}

	// Get the device flags
	ifrf := ifReq{Name: devName}
	if err = ioctl(fd, unix.SIOCGIFFLAGS, uintptr(unsafe.Pointer(&ifrf))); err != nil {
		return fmt.Errorf("failed to get tun flags: %s", err)
	}

	linkAddr, err := getLinkAddr(t.Device)
	if err != nil {
		return err
	}
	if linkAddr == nil {
		return fmt.Errorf("unable to discover link_addr for tun interface")
	}
	t.linkAddr = linkAddr

	for _, network := range t.vpnNetworks {
		if network.Addr().Is4() {
			err = t.activate4(network)
			if err != nil {
				return err
			}
		} else {
			err = t.activate6(network)
			if err != nil {
				return err
			}
		}
	}

	// Run the interface

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Restart nebula so the utun is recreated and its link address registered before Activate.
  2. Verify tun.dev matches the actual interface name from the utun connect step.
  3. Update macOS if the kernel intermittently omits AF_LINK entries for fresh utun devices.
  4. Stop competing VPN software that may be manipulating the interface table concurrently.
Defensive patterns

Strategy: retry

Try / catch

if err := start(); err != nil && strings.Contains(err.Error(), "unable to discover link_addr") {
    // interface registered without link addr: retry startup once
}

Prevention

When it happens

Trigger: getLinkAddr(t.Device) returns (nil, nil) during tun.Activate — the utun interface exists but has no AF_LINK sockaddr entry, e.g. the interface was just created and is not fully registered, or the name lookup matched nothing enumerable.

Common situations: Interface torn down between creation and Activate; macOS kernel state where the utun lacks a link-layer address; dev name mismatch so enumeration finds no matching interface.

Related errors


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