slackhq/nebula · error
failed to set tun address %s: %s
Error message
failed to set tun address %s: %s
What it means
addIp configures an IPv4 address on the FreeBSD tun interface via the SIOCAIFADDR ioctl on a routing socket. When that ioctl fails, the address string and the raw errno are wrapped in this error. It means the kernel rejected the ifaliasreq for this interface/address combination.
Source
Thrown at overlay/tun_freebsd.go:433
Len: unix.SizeofSockaddrInet4,
Family: unix.AF_INET,
Addr: getBroadcast(cidr).As4(),
},
MaskAddr: unix.RawSockaddrInet4{
Len: unix.SizeofSockaddrInet4,
Family: unix.AF_INET,
Addr: prefixToMask(cidr).As4(),
},
VHid: 0,
}
s, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, unix.IPPROTO_IP)
if err != nil {
return err
}
defer syscall.Close(s)
// Note: unix.SIOCAIFADDR corresponds to FreeBSD's OSIOCAIFADDR
if err := ioctl(uintptr(s), unix.SIOCAIFADDR, uintptr(unsafe.Pointer(&ifr))); err != nil {
return fmt.Errorf("failed to set tun address %s: %s", cidr.Addr().String(), err)
}
return nil
}
if cidr.Addr().Is6() {
ifr := ifreqAlias6{
Name: t.deviceBytes(),
Addr: unix.RawSockaddrInet6{
Len: unix.SizeofSockaddrInet6,
Family: unix.AF_INET6,
Addr: cidr.Addr().As16(),
},
PrefixMask: unix.RawSockaddrInet6{
Len: unix.SizeofSockaddrInet6,
Family: unix.AF_INET6,
Addr: prefixToMask(cidr).As16(),
},
Lifetime: addrLifetime{View on GitHub (pinned to dd8f660c0a)
Solutions
- Check the wrapped errno in the message — EPERM/EACCES means run as root or grant privileges; EINVAL/EADDRNOTAVAIL means the address/subnet is invalid
- Ensure the configured CIDR is a valid IPv4 prefix (e.g. 10.0.0.1/24) and the address is inside the declared network
- Verify the tun device was created and named correctly before Activate is called
- Check kernel logs (dmesg) for ifconfig/ioctl rejections
Example fix
// before
vpnNetworks: []netip.Prefix{netip.MustParsePrefix("10.0.0.1/16")}, // host bits set
// after
p, _ := netip.ParsePrefix("10.0.0.1/16")
p = p.Masked() // 10.0.0.0/16
vpnNetworks: []netip.Prefix{netip.MustParsePrefix("10.0.0.1/16"), } // ensure .Masked() applied where required Defensive patterns
Strategy: validation
Validate before calling
p, err := netip.ParsePrefix(cfgAddr)
if err != nil || !p.Addr().Is4() {
return fmt.Errorf("invalid IPv4 tun address %q", cfgAddr)
} Type guard
func isIPv4Prefix(p netip.Prefix) bool { return p.IsValid() && p.Addr().Is4() } Try / catch
if err := dev.Activate(); err != nil {
var serr syscall.Errno
if strings.Contains(err.Error(), "failed to set tun address") && errors.As(err, &serr) && (serr == syscall.EPERM || serr == syscall.EACCES) {
return fmt.Errorf("insufficient privileges to assign tun address: %w", err)
}
return err
} Prevention
- Validate IPv4 prefixes at config load with netip.ParsePrefix
- Run with root/privileges when configuring interface addresses
- Ensure the tun device exists and is open before Activate
- Mask host bits or ensure address/subnet consistency before ioctl
When it happens
Trigger: Calling Activate() (which calls addIp per configured VPN network prefix) where the ioctl SIOCAIFADDR on the routing socket returns an error — invalid CIDR, address not belonging to the interface's subnet, or device not properly opened.
Common situations: Configuring an address whose subnet doesn't match the destination in the ifreq; the tun interface not yet up / wrong device name; running without sufficient privileges (ioctl on routing socket requires root or CAP_NET_ADMIN-equivalent on FreeBSD); malformed vpnNetworks config.
Related errors
- unable to discover link_addr for tun interface
- failed to set tun address %s: %s
- unable to determine IP version from packet
- failed to set tun v4 address: %s
- unable to determine IP version from packet
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/bf112f9255455f4d.
Report an issue: GitHub.